Create a draft
Save a finished piece of short-form content — an X post or thread, a LinkedIn post, a one-off email, or an X Article — to your publication's library.
What this does:
- The piece is saved as a draft and shows up in the Paragraph app under Content, where you can edit it and send it.
- Nothing is posted, emailed, or scheduled. Sending happens in the app, so a draft you upload can't go out without you.
- Long-form Paragraph posts are a different resource — use
POST /v1/postsfor those.
The body:
bodycarries the artifact itself, in the shape its kind uses (see the field descriptions below).- It's validated the same way the Paragraph app validates it, so an X thread over 280 characters an entry, or an Article missing its headline, comes back with the same explanation you'd see in the app.
- Drafts created here are text-only. Media has to be uploaded to X or LinkedIn first, which the API can't do yet.
Grouping:
- Pass
bucketIdto group this piece with the post it was made from, so the writer sees them together as one row under Content. Get the id withPOST /v1/posts/{postId}/bucket. - Unknown fields are rejected rather than ignored, so a misspelled key comes back as a 400 instead of a draft that quietly isn't grouped.
apiKeyAuthorizationBearer <token>API key for authenticating protected endpoints. Pass as Bearer token in Authorization header.
Body
application/json- body
kind*stringWhat kind of piece this is
"tweet""linkedin""newsletter""x_article"title*stringWhat this piece is called in your library. Sentence case, no trailing period. Not published anywhere — for an X Article headline, use body.title.
1 <= length <= 200body*The artifact itself, in the shape this kind uses
bucketId?stringGroup this piece with the post it was made from, so the writer sees them together in Content. Get the id from POST /v1/posts/{postId}/bucket. Omit for standalone work that isn't derived from anything.
uuidDraft created successfully
application/json- response
id*stringUnique identifier for this piece of content
kind*stringWhat this piece is: tweet, linkedin, newsletter, or x_article
title*stringWhat this piece is called in your library
excerpt*stringFirst readable line of the body, for listing views
status*stringWhether this piece has been delivered, is still a draft, or was archived
"draft""published""archived"scheduled*booleanWhether a scheduled send is queued against this piece
lockedReason*|Why this piece can't be edited right now, or null when it can. A queued or in-flight send locks the words, because they go out exactly as written.
publishedAt*|ISO 8601 timestamp of the first delivery, or null
url*|Where this piece went live, from the same delivery publishedAt came from. Null when it hasn't been delivered, and null by design for a channel that publishes no page: a custom email renders into the message itself, so there is no address to link to. Never guessed — a delivery whose id isn't shaped like its channel reports null rather than a link that would 404.
archivedAt*|ISO 8601 timestamp of when this piece was archived, or null
bucketId*|The bucket grouping this piece with the post it was made from, or null when it stands alone. Read it back with GET /v1/buckets/{bucketId}.
createdAt*stringISO 8601 timestamp of creation
updatedAt*stringISO 8601 timestamp of the last change
body*The artifact itself, in the shape its kind uses
curl -X POST "https://example.com/v1/content" \ -H "Content-Type: application/json" \ -d '{ "kind": "tweet", "title": "string", "body": {} }'{ "id": "string", "kind": "string", "title": "string", "excerpt": "string", "status": "draft", "scheduled": true, "lockedReason": "string", "publishedAt": "string", "url": "string", "archivedAt": "string", "bucketId": "string", "createdAt": "string", "updatedAt": "string", "body": { "property1": null, "property2": null }}List your drafted content GET
Retrieve a paginated list of the short-form content in your publication's library, newest activity first. The publication is identified by the API key. Filter with `kind` and `status`. `status` defaults to `all`, which is everything except the pieces you've archived — a piece that was delivered stays listed whether or not it was archived afterwards. Bodies aren't included; fetch a single piece to read one.
Get a piece of content GET
Retrieve one piece of drafted content with its body. Read it before editing so you rewrite what's actually saved — the draft may have changed in the app.