DocumentationAPI reference

API reference

v1

One contract for profiles, accounts, posts, media, analytics, comments and delivery events.

Base URL
https://castrook.com/api/v1

Requests and responses use JSON with snake_case fields. Every response includes x-request-id and rate-limit headers. Dates use ISO 8601 with an explicit timezone.

Endpoints

GET/profilesList customer profiles
POST/profilesCreate a profile
GET/profiles/{id}Get a profile
PATCH/profiles/{id}Update a profile
DELETE/profiles/{id}Delete an empty profile
POST/connect-sessionsCreate hosted/embedded onboarding
GET/connect-sessions/{id}Inspect a connection session
DELETE/connect-sessions/{id}Revoke a connection link
GET/mediaList private media
POST/media/uploadsCreate a direct upload ticket
POST/media/{id}/completeVerify and freeze upload
GET/media/{id}Get private asset metadata
GET/media/{id}/contentRead an authenticated preview
DELETE/media/{id}Delete unused media
GET/analytics/postsRead destination metrics
GET/analytics/summaryRead totals and coverage
POST/posts/{id}/analytics/refreshRefresh post performance
GET/accountsList accounts
POST/accountsCreate a test account
PATCH/accounts/{id}Assign or clear account profile
POST/accounts/{id}/analytics-consentRecord explicit YouTube analytics privacy acceptance
DELETE/accounts/{id}Disconnect account
GET/accounts/{id}/publishing-optionsGet TikTok creator settings
GET/accounts/{id}/boardsList Pinterest boards
GET/accounts/{id}/boards/{board_id}/sectionsList Pinterest board sections
GET/postsList posts
POST/postsCreate or schedule a post
GET/posts/{id}Get post and targets
DELETE/posts/{id}Cancel a pending post
GET/commentsList comments
POST/commentsReply to a comment
GET/webhooksList endpoints
POST/webhooksCreate an endpoint
DELETE/webhooks/{id}Disable endpoint
GET/deliveriesList webhook deliveries
GET/logsList request logs
GET/usageGet plan usage and limits

Download the complete OpenAPI specification for all schemas, response codes, and query parameters.

Create a post

POST /posts requires an Idempotency-Key header. A new post returns HTTP 202; an identical replay returns HTTP 200 and Idempotency-Replayed: true.

FieldTypeDescription
textstringPost caption. Maximum 5,000 characters; platform limits also apply. Empty is valid with media or a LinkedIn article URL.
account_idsstring[]One or more account IDs in the same workspace and mode.
mediaobject · optionalLegacy single { url, type }. HTTPS URL and video or image. Use either media or media_items.
scheduled_atstring · optionalISO 8601 timestamp at least 5 seconds in the future, up to 1 year ahead.
profile_idstring · optionalCustomer profile for this post and its destinations.
media_itemsobject[] · optionalOrdered { type, url } or { type, asset_id } items; provider bounds apply.
formatstring · optionalfeed, reel, story or video, where the platform supports it.
destinationsobject[] · optionalPer-account caption, media, format and options overrides
platform_optionsobject · optionalPlatform-specific visibility, consent, and publishing choices
JSON
{
  "text": "Made to be shared.",
  "account_ids": ["acc_instagram", "acc_youtube"],
  "media": {
    "url": "https://your-cdn.com/launch.mp4",
    "type": "video"
  },
  "platform_options": {
    "youtube": {
      "privacy_status": "private",
      "made_for_kids": false
    }
  }
}

The post response

JSON
{
  "data": {
    "id": "pst_example",
    "text": "Made to be shared.",
    "status": "queued",
    "mode": "test",
    "scheduled_at": null,
    "created_at": "2026-09-26T12:00:00.000Z",
    "updated_at": "2026-09-26T12:00:00.000Z",
    "targets": [
      {
        "account_id": "acc_instagram",
        "platform": "instagram",
        "status": "queued",
        "attempts": 0
      }
    ]
  }
}

Targets can include provider_post_id, url, or an error object when the platform provides them. A successful private post may have no public URL. YouTube identifiers and links are refreshed while authorization remains valid; they can disappear after disconnection, deletion on YouTube, or expiry of an unrefreshable record. The historical delivery state is not a guarantee that a video is still available.

Pagination and filtering

List responses return data plus meta.next_cursor and meta.has_more. Pass the next cursor unchanged. Posts support status, platform, q, cursor, and limit filters. q matches a caption substring, ignoring case. Keep filters unchanged while paging; cursors are bound to those filters.

JSON
{
  "data": [],
  "meta": { "next_cursor": null, "has_more": false }
}