Skip to Content
For developersGuidesSeed to scheduled post

Seed to scheduled post

This walkthrough goes the whole way: pick a seed, generate a social post with a visual, tune it, and schedule it to your connected accounts. You will need a key with the Content creation group for the middle steps and the Scheduling group for the calendar steps; reads use the Read access group. Prices for the metered steps are on the live price table; every response states its own creditsCharged.

The whole flow

Pick a seed, or plant one

Seeds are the topics content grows from. List what you already have:

GET /api/v1/seeds?search=rates&limit=10

Or save your own:

POST /api/v1/seeds
{ "title": "What a rate dip means for spring buyers", "content": "Rates eased this week. For buyers who paused their search last fall...", "category": "purchase" }

Saving a seed is free and returns 201 with the stored seed and its id. It runs no model; the seed holds your material as you wrote it.

Generate a social post with a visual

POST /api/v1/creations/generate
{ "type": "social_post", "seed_id": "0a1b2c3d-0000-4000-8000-000000000000", "include_visual": true, "aspect_ratio": "square", "media_style": "photorealistic" }

The response is 201 with the finished creation: caption, alt text, and the generated image as a stored URL. Nothing streams; the call settles when the work is done, and the caption and image together cost one flat social post charge. Prefer your own picture? Pass image_asset_id instead of include_visual, per Bring your own image.

{ "creation": { "id": "5e6f7a8b-0000-4000-8000-000000000000", "type": "social_post", "url": "https://hub.truetone.ai/creations/social_post/5e6f7a8b-0000-4000-8000-000000000000", "body": { "type": "social_post", "caption": "Rates eased this week, and that changes the math for spring buyers...", "altText": "A front porch in morning light", "imageUrl": "https://..." } } }

The full response also carries creditsCharged, the amount this call actually captured.

Regenerate until it is right

Not quite there? Regenerate in place. The creation keeps its id; the call rewrites and saves in one step, answering 200 because nothing new was created.

POST /api/v1/creations/regenerate
{ "type": "social_post", "creation_id": "5e6f7a8b-0000-4000-8000-000000000000", "parts": "caption", "change_instructions": "Lead with the question, drop the exclamation points." }

parts controls what is redone on a social post: caption, image, or both (the default). Each part has its own price, and a both call prices the image at its bundled rate, so the pair together costs less than two standalone calls would. On a both call the save is all-or-nothing: if the image leg fails, the old post stands untouched and everything reserved is released.

See where you can post

GET /api/v1/schedule/targets
{ "targets": [ { "platform": "linkedin", "accountId": "acct_example_1", "label": "Jordan Example", "readyToPost": true, "blockedReason": null } ], "manageUrl": "https://hub.truetone.ai/account/social" }

Targets are the social accounts already connected in the dashboard; the API never connects new ones. An account that needs attention still appears, with readyToPost: false and a blockedReason telling the person what to fix, at manageUrl.

Schedule it

POST /api/v1/schedule
{ "type": "social_post", "creation_id": "5e6f7a8b-0000-4000-8000-000000000000", "scheduled_time": "2026-09-02T15:30:00Z", "targets": ["linkedin"] }

Name targets by platform, or by accountId when you have two accounts on one platform. The time must be at least five minutes out. The post’s caption and image come from the creation itself; nothing in this request can override the content, which is why you tuned it in the step before. Scheduling is free.

⚠️

Read post.status in the response. A provider rejection still answers 200, with the stored post carrying status: "failed" and an errorMessage, exactly as the dashboard calendar shows it. The stored row is your ground truth, so check it rather than the status code alone.

Change your mind

DELETE /api/v1/schedule/9c0d1e2f-0000-4000-8000-000000000000
{ "id": "9c0d1e2f-0000-4000-8000-000000000000", "cancelled": true, "providerPostWithdrawn": true }

Cancellation withdraws the post from the publishing provider first and only then removes it from your calendar, so you are never left with a deleted row and a still-live post. If the provider cannot be reached, the call answers 502 distribution_failed with retryable: true and keeps the row so you can try again.

Where this can refuse

Each step can refuse for its own reasons: 404 not_found for a seed or creation that is not yours, 409 not_schedulable when a creation is missing what the calendar needs, 502 distribution_failed when the provider is the problem, and the budget refusals from Credits and billing. Every one is catalogued on the Errors page.

Last updated on