Ghost
Let hires read your Ghost posts, write and change drafts, and publish or schedule them, by email too, once a person approves.
Explore 7 actions and their permissionsExact inputs, sign-in scopes, access limits and approval rules.
With Ghost (Ghost(Pro) or your own server), a hire can:
- list posts (drafts, scheduled, published) and read one, with its email results if it was sent,
- list the newsletters a post can be emailed to,
- write a post as a draft, and change a draft,
- publish a draft now, or schedule it, on your site and optionally by email to a newsletter's members, once a person approves.
1. Make an integration in Ghost
Straight there: https://<your-site>/ghost/#/settings/integrations/new. Once you've typed your site's address in Roster, the form links to it.
- In Ghost, open Settings → Integrations and click Add custom integration. Name it
Roster. - Copy the Admin API key and the API URL shown with it.
The key can change anything on your site, so Roster keeps it sealed: hires never see it, and every request Roster makes is signed with a fresh token that stops working after five minutes.
2. Connect it in Roster
- Open Integrations → Tools → Add a tool, search for Ghost and choose it.
- Admin API key: paste it.
- Ghost address: the API URL, like
https://blog.example.com. - Click Connect.
Roster checks the key when you click Connect. If what you paste doesn't look like a key (an Admin API key is two hex parts joined by a colon, id:secret), the form says so straight away. Once it's accepted, the connection shows Connected as your site's title. If it's refused, Roster says what to fix (a mistyped key, a missing permission) and saves nothing.
3. Give hires access
On the hire's Tools tab, click Give access on Ghost:
- Read only: posts and newsletters.
- Read and write: also write and change drafts, and publish or schedule posts (always with approval).
- Newsletters it may email: newsletter slugs it may email a post to when publishing. Leave it empty for any active newsletter.
Hires only change drafts. A post that's already published or scheduled isn't changed through Roster.
Publishing always asks first
Publishing is public, and with a newsletter it emails your members, so publishing or scheduling a post waits for a person's approval. The approver sees the title, whether it's emailed and to whom, and the post's version. If anyone changes the post after that, Roster won't publish it. A post is only emailed when the hire names a newsletter.
If something goes wrong
- "Invalid token" or "Unknown Admin API Key": the integration was deleted or its key regenerated; paste the new key.
- "Saving failed! Someone else is editing this post": the draft changed in Ghost while the hire worked on it. The hire reads it again and retries.
- "Only a draft can be published or scheduled here": the post is already live or scheduled.
Tools and permissions reference
This reference is built from the same definitions Roster uses to connect Ghost and give hires access. It updates with each release.
Authentication and requested permissions
The account or app you connect sets the outer limit. Each hire's access can narrow it further. Connecting a tool gives it to no hire until you give access on that hire's Tools tab.
API key or access token
In Ghost: Settings → Integrations → Add custom integration → copy the Admin API key.
No fixed permission list is declared for this connection. Review the sign-in consent screen, the account's roles, and the service's own documentation before connecting.
Connection fields
| Field | What to provide |
|---|---|
Admin API keytokenRequired · sealed secret | In Ghost: Settings → Integrations → Add custom integration → copy the Admin API key. |
Ghost addressurlRequired | Your site's admin address: the API URL shown with the key (without /ghost). |
Per-hire limits
Read-only hires receive only actions that read. Read-and-write access also allows actions that change things, where the connection itself permits them. An empty resource allowlist usually means everything the connected account can reach; each field below explains its meaning.
| Field | What to provide |
|---|---|
Newsletters it may emailnewslettersOptional | Newsletter slugs it may email a post to when publishing. Leave empty for any active newsletter (publishing always asks a person first). |
Actions
7 actions: 3 only read and 4 change something. A read action may still need approval when your workspace or hire is set to ask. A locked approval requirement always applies.
7 of 7 actions. Open an action for its arguments and full input schema.
list_postsRead only
Ghost posts, recently changed first: drafts, scheduled or published, by words in the title.
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
statusOptional | "draft" | "scheduled" | "published" | See input schema below. |
searchOptional | string | See input schema below. |
limitOptional | integer | See input schema below.Default: 15 |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"draft",
"scheduled",
"published"
]
},
"search": {
"type": "string",
"maxLength": 150
},
"limit": {
"default": 15,
"type": "integer",
"minimum": 1,
"maximum": 50
}
}
}get_postRead only
One Ghost post: status, tags, authors, excerpt, what it says, its email results if it was sent, and its version (needed to publish or schedule it).
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
postRequired | string | the post's ID |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"post": {
"type": "string",
"description": "the post's ID"
}
},
"required": [
"post"
]
}list_newslettersRead only
The site's newsletters a post can be emailed to, with how many members each has.
Approval: Uses your workspace and hire approval settings.
This action takes no arguments.
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {}
}create_draftRead and write
Write a post as a draft in Ghost for a person to check. Nobody sees it until it's published. It goes out in the business's name: write as the business, never sign with a person's name or say you're one.
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
titleRequired | string | See input schema below. |
bodyRequired | string | See input schema below. |
formatOptional | "text" | "html" | text: plain text, paragraphs on blank lines; html: your HTMLDefault: "text" |
tagsOptional | string[] | tag names (new ones are made) |
excerptOptional | string | See input schema below. |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"title": {
"type": "string",
"minLength": 1,
"maxLength": 255
},
"body": {
"type": "string",
"minLength": 1,
"maxLength": 200000
},
"format": {
"default": "text",
"description": "text: plain text, paragraphs on blank lines; html: your HTML",
"type": "string",
"enum": [
"text",
"html"
]
},
"tags": {
"description": "tag names (new ones are made)",
"maxItems": 10,
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 190
}
},
"excerpt": {
"type": "string",
"maxLength": 300
}
},
"required": [
"title",
"body"
]
}update_draftRead and write
Change a draft Ghost post: its title, content, tags or excerpt. Published and scheduled posts can't change here.
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
postRequired | string | the post's ID |
titleOptional | string | See input schema below. |
bodyOptional | string | See input schema below. |
formatOptional | "text" | "html" | the body's format, with body (default text) |
tagsOptional | string[] | replaces the post's tags |
excerptOptional | string | See input schema below. |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"post": {
"type": "string",
"description": "the post's ID"
},
"title": {
"type": "string",
"minLength": 1,
"maxLength": 255
},
"body": {
"type": "string",
"minLength": 1,
"maxLength": 200000
},
"format": {
"description": "the body's format, with body (default text)",
"type": "string",
"enum": [
"text",
"html"
]
},
"tags": {
"description": "replaces the post's tags",
"maxItems": 10,
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 190
}
},
"excerpt": {
"type": "string",
"maxLength": 300
}
},
"required": [
"post"
]
}publish_postRead and write
Publish a draft Ghost post now, on the site and, with a newsletter, by email to its members. It's public, so it waits for a person's approval: Roster asks in the thread with the title, the email and the version, and publishes exactly that, once, when they approve. It goes out in the business's name: write as the business, never sign with a person's name or say you're one.
Approval: Always asks for approval.
| Argument | Type | Details |
|---|---|---|
postRequired | string | the post's ID |
titleRequired | string | its title, exactly as get_post shows it |
versionRequired | string | its version, from get_post |
newsletterOptional | string | a newsletter's slug to email the post to its members; leave out to publish on the site only |
email_segmentOptional | "all" | "free" | "paid" | which members get the email (default all) |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"post": {
"type": "string",
"description": "the post's ID"
},
"title": {
"type": "string",
"maxLength": 300,
"description": "its title, exactly as get_post shows it"
},
"version": {
"type": "string",
"pattern": "^[0-9a-f]{10}$",
"description": "its version, from get_post"
},
"newsletter": {
"description": "a newsletter's slug to email the post to its members; leave out to publish on the site only",
"type": "string"
},
"email_segment": {
"description": "which members get the email (default all)",
"type": "string",
"enum": [
"all",
"free",
"paid"
]
}
},
"required": [
"post",
"title",
"version"
]
}schedule_postRead and write
Schedule a draft Ghost post to publish (and, with a newsletter, email) at a time. It's public, so it waits for a person's approval, as publish_post does. It goes out in the business's name: write as the business, never sign with a person's name or say you're one.
Approval: Always asks for approval.
| Argument | Type | Details |
|---|---|---|
postRequired | string | the post's ID |
titleRequired | string | its title, exactly as get_post shows it |
versionRequired | string | its version, from get_post |
newsletterOptional | string | a newsletter's slug to email the post to its members; leave out to publish on the site only |
email_segmentOptional | "all" | "free" | "paid" | which members get the email (default all) |
atRequired | string | when, ISO 8601 with a time zone |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"post": {
"type": "string",
"description": "the post's ID"
},
"title": {
"type": "string",
"maxLength": 300,
"description": "its title, exactly as get_post shows it"
},
"version": {
"type": "string",
"pattern": "^[0-9a-f]{10}$",
"description": "its version, from get_post"
},
"newsletter": {
"description": "a newsletter's slug to email the post to its members; leave out to publish on the site only",
"type": "string"
},
"email_segment": {
"description": "which members get the email (default all)",
"type": "string",
"enum": [
"all",
"free",
"paid"
]
},
"at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
"description": "when, ISO 8601 with a time zone"
}
},
"required": [
"post",
"title",
"version",
"at"
]
}Watches and incoming events
- No built-in watch is declared. Give a hire a scheduled responsibility if it should check this service regularly.
- No incoming webhook handler is declared for this integration.
Limits and troubleshooting
- Permission errors: check both the connected account's rights and the hire's resource and read/write limits.
- Expired or revoked access: reconnect or replace the key on the connection.
- Rate limits and unavailable services can interrupt work. The hire's timecard records the outcome.
- The action schema describes accepted inputs. It does not grant additional access or bypass approvals.