Skip to content
Content Rabbit

API keys are team-scoped. Rotate keys regularly and delete unused keys immediately.

Base URL & Authentication

All requests target the versioned API base URL and must include a Bearer token.

Base URL: https://contentrabbitai.com/api/public/v1
Authorization: Bearer YOUR_API_KEY

Getting an API Key

  1. Open Settings > Team.
  2. Choose the team you want to automate.
  3. Go to the API & Integrations tab and press Generate API key.
  4. Copy the value immediately — you can always rotate to get a fresh key.

Rate Limiting

Every API key is rate-limited per minute. Limits vary by plan tier. Inspect the response headers to track usage:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per window
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUnix timestamp when the window resets

Exceeding limits returns 429 Too Many Requests. Retry with exponential backoff.

Pagination

The API supports two pagination modes (do not combine them).

Cursor-based (default)

Pass the nextCursor value from the previous response as the cursor query parameter. This mode requires the default sort (createdAt desc).

{
  "paging": {
    "nextCursor": "clx9abc123",
    "page": null,
    "total": null
  }
}

Page-based

Pass page=N (1-indexed). The response includes total, pages, and limit in the paging object.

{
  "paging": {
    "nextCursor": null,
    "page": 2,
    "limit": 25,
    "total": 142,
    "pages": 6
  }
}

Error Format

All errors return a JSON body with a requestId for tracing:

{
  "requestId": "key_abc123",
  "error": "Post not found",
  "details": null
}

Common HTTP status codes:

StatusMeaning
400Invalid request parameters or body
401Missing or invalid API key
402Plan limit reached
403Insufficient permissions
404Resource not found
409Conflict (concurrent modification)
429Rate limit exceeded

Quick Start

List recent posts

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/posts?limit=10&status=draft"

Create and schedule a post

curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "platformType": "twitter",
    "content": "Hello from the API!",
    "title": "My first API post",
    "status": "draft"
  }' \
  "https://contentrabbitai.com/api/public/v1/posts"

Then schedule it:

curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "scheduledAt": "2025-06-01T10:00:00Z",
    "selectedPlatforms": ["twitter", "linkedin"]
  }' \
  "https://contentrabbitai.com/api/public/v1/posts/POST_ID/schedule"

Publish immediately

curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "platforms": ["twitter", "linkedin"]
  }' \
  "https://contentrabbitai.com/api/public/v1/posts/POST_ID/publish"

Posts

GET
/posts

List posts with cursor-based or page-based pagination and filters.

NameTypeRequiredDescription
limitintegerNoMaximum number of posts to return.
cursorstringNoCursor from the previous page.
pageintegerNo1-indexed page number.
statusstringNoFilter by post status.
platformstringNoFilter by platform type.
searchstringNoSearch post titles.
startDatedate-timeNoEarliest post creation date.
endDatedate-timeNoLatest post creation date.
sortBystringNoField to sort by.
sortOrderstringNoSort direction.
includestringNoComma-separated optional fields.
curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/posts"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": [
    {
      "id": "post_p3k9m2x7q4t1w8z6c5v0b3n",
      "status": "scheduled",
      "platformType": "linkedin",
      "title": "Weekly update",
      "content": null,
      "tags": [
        "update",
        "product"
      ],
      "mediaIds": [],
      "category": null,
      "scheduledAt": "2025-06-01T10:00:00.000Z",
      "createdAt": "2025-05-28T16:40:00.000Z",
      "updatedAt": "2025-05-28T16:40:00.000Z"
    }
  ],
  "paging": {
    "nextCursor": "post_p3k9m2x7q4t1w8z6c5v0b3n"
  },
  "meta": {
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6",
    "totalReturned": 1
  }
}
POST
/posts

Create a new draft or scheduled post.

NameTypeRequiredDescription
platformTypestringYesPrimary platform.
contentstringNoPost content.
titlestringNoPost title.
statusstringNoPost status.
scheduledAtdate-timeNoOptional scheduled time.
tagsstring[]NoPost tags.
categorystringNoPost category.
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "platformType": "linkedin",
  "title": "Weekly update",
  "content": "Here is what we shipped this week...",
  "tags": [
    "update",
    "product"
  ],
  "category": "announcements"
}' \
  "https://contentrabbitai.com/api/public/v1/posts"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "post_p3k9m2x7q4t1w8z6c5v0b3n",
    "status": "draft",
    "platformType": "linkedin",
    "scheduledAt": null,
    "createdAt": "2025-05-28T16:40:00.000Z",
    "updatedAt": "2025-05-28T16:40:00.000Z"
  },
  "meta": {
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6"
  }
}
GET
/posts/{postId}

Fetch a single post by ID.

NameTypeRequiredDescription
includestringNoComma-separated optional fields.
curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/posts/{postId}"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "post_p3k9m2x7q4t1w8z6c5v0b3n",
    "status": "scheduled",
    "platformType": "linkedin",
    "title": "Weekly update",
    "content": null,
    "tags": [
      "update",
      "product"
    ],
    "mediaIds": [],
    "category": "announcements",
    "scheduledAt": "2025-06-01T10:00:00.000Z",
    "createdAt": "2025-05-28T16:40:00.000Z",
    "updatedAt": "2025-05-28T16:40:00.000Z",
    "platformSettings": {
      "selectedPlatforms": [
        "twitter",
        "linkedin"
      ],
      "linkedin": {
        "content": "Here is what we shipped this week..."
      }
    },
    "publishedPlatforms": [],
    "platformResults": {
      "twitter": {
        "status": "scheduled",
        "scheduledAt": "2025-06-01T10:00:00.000Z"
      },
      "linkedin": {
        "status": "scheduled",
        "scheduledAt": "2025-06-01T10:00:00.000Z"
      }
    }
  }
}
PATCH
/posts/{postId}

Partially update a post. Only provided fields change.

NameTypeRequiredDescription
contentstringNoUpdated post content.
titlestringNoUpdated post title.
statusstringNoUpdated post status.
tagsstring[]NoUpdated post tags.
scheduledAtdate-timeNoUpdated scheduled time.
curl -X PATCH \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "content": "Updated content",
  "title": "Updated title"
}' \
  "https://contentrabbitai.com/api/public/v1/posts/{postId}"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "post_p3k9m2x7q4t1w8z6c5v0b3n",
    "status": "scheduled",
    "platformType": "linkedin",
    "title": "Updated title",
    "content": null,
    "tags": [
      "update",
      "product"
    ],
    "mediaIds": [],
    "category": "announcements",
    "scheduledAt": "2025-06-01T10:00:00.000Z",
    "createdAt": "2025-05-28T16:40:00.000Z",
    "updatedAt": "2025-05-28T16:40:00.000Z",
    "platformSettings": {
      "selectedPlatforms": [
        "twitter",
        "linkedin"
      ],
      "linkedin": {
        "content": "Here is what we shipped this week..."
      }
    },
    "publishedPlatforms": [],
    "platformResults": {
      "twitter": {
        "status": "scheduled",
        "scheduledAt": "2025-06-01T10:00:00.000Z"
      },
      "linkedin": {
        "status": "scheduled",
        "scheduledAt": "2025-06-01T10:00:00.000Z"
      }
    }
  }
}
DELETE
/posts/{postId}

Delete a post.

curl -X DELETE \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/posts/{postId}"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "post_p3k9m2x7q4t1w8z6c5v0b3n",
    "deleted": true
  }
}
POST
/posts/{postId}/publish

Publish a post immediately to selected platforms.

NameTypeRequiredDescription
platformsstring[]NoOptional platform overrides.
firstCommentstringNoOptional first comment.
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "platforms": [
    "twitter"
  ],
  "firstComment": "Thread continues below..."
}' \
  "https://contentrabbitai.com/api/public/v1/posts/{postId}/publish"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "results": [
      {
        "platform": "twitter",
        "success": true,
        "status": "published",
        "postUrl": "https://twitter.com/contentrabbit/status/1798765432109876543",
        "externalId": "1798765432109876543",
        "publishedAt": "2025-05-30T14:00:00.000Z"
      }
    ]
  }
}
POST
/posts/{postId}/retry

Retry publishing for platforms that previously failed.

curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/posts/{postId}/retry"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "results": [
      {
        "platform": "twitter",
        "success": true,
        "status": "published",
        "postUrl": "https://twitter.com/contentrabbit/status/1798765432109876543",
        "publishedAt": "2025-05-30T14:00:00.000Z"
      },
      {
        "platform": "linkedin",
        "success": false,
        "status": "failed",
        "error": "Platform API returned HTTP 429"
      }
    ]
  }
}
GET
/posts/{postId}/status

Get the current publish status and per-platform results.

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/posts/{postId}/status"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "post_p3k9m2x7q4t1w8z6c5v0b3n",
    "status": "error",
    "scheduledAt": "2025-06-01T10:00:00.000Z",
    "platformResults": {
      "twitter": {
        "status": "published",
        "publishedAt": "2025-06-01T10:00:04.000Z",
        "postUrl": "https://twitter.com/contentrabbit/status/1798765432109876543",
        "externalId": "1798765432109876543"
      },
      "linkedin": {
        "status": "failed",
        "error": "Platform API returned HTTP 429"
      }
    },
    "publishedPlatforms": [
      "twitter"
    ],
    "updatedAt": "2025-06-01T10:00:04.000Z"
  }
}
POST
/posts/{postId}/schedule

Set or update the scheduled time for a post.

NameTypeRequiredDescription
scheduledAtdate-timeYesWhen to publish.
selectedPlatformsstring[]NoOptional platform overrides.
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "scheduledAt": "2025-06-01T10:00:00Z",
  "selectedPlatforms": [
    "twitter",
    "linkedin"
  ]
}' \
  "https://contentrabbitai.com/api/public/v1/posts/{postId}/schedule"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "post_p3k9m2x7q4t1w8z6c5v0b3n",
    "status": "scheduled",
    "scheduledAt": "2025-06-01T10:00:00.000Z",
    "platformResults": {
      "twitter": {
        "status": "scheduled",
        "scheduledAt": "2025-06-01T10:00:00.000Z"
      },
      "linkedin": {
        "status": "scheduled",
        "scheduledAt": "2025-06-01T10:00:00.000Z"
      }
    },
    "platformSettings": {
      "selectedPlatforms": [
        "twitter",
        "linkedin"
      ]
    },
    "updatedAt": "2025-05-28T16:41:00.000Z"
  }
}
DELETE
/posts/{postId}/schedule

Remove the scheduled time and return the post to draft status.

curl -X DELETE \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/posts/{postId}/schedule"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "post_p3k9m2x7q4t1w8z6c5v0b3n",
    "status": "draft",
    "scheduledAt": null,
    "platformResults": {},
    "updatedAt": "2025-05-28T16:42:00.000Z"
  }
}

Teams

GET
/teams

List teams available to the API key.

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/teams"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": [
    {
      "id": "tm_w8z2q6t4m1x7c9v3b5n0k2j6",
      "name": "Marketing team",
      "avatarUrl": "https://example.com/avatar.png",
      "defaultPlatforms": [
        "twitter",
        "linkedin"
      ],
      "primaryPlatform": "twitter",
      "scheduleTimezone": "America/New_York",
      "scheduleSlots": [
        {
          "id": "slot-1",
          "day": "monday",
          "time": "09:00"
        }
      ],
      "settings": {}
    }
  ]
}
POST
/teams

Create a new team.

NameTypeRequiredDescription
namestringYesTeam name.
avatarUrlstringNoTeam avatar URL.
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Marketing team",
  "avatarUrl": "https://example.com/avatar.png"
}' \
  "https://contentrabbitai.com/api/public/v1/teams"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "tm_w8z2q6t4m1x7c9v3b5n0k2j6",
    "name": "Marketing team",
    "avatarUrl": "https://example.com/avatar.png",
    "defaultPlatforms": [
      "twitter",
      "linkedin"
    ],
    "primaryPlatform": "twitter",
    "scheduleTimezone": "America/New_York",
    "scheduleSlots": [
      {
        "id": "slot-1",
        "day": "monday",
        "time": "09:00"
      }
    ],
    "settings": {}
  },
  "meta": {
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6"
  }
}
GET
/teams/{teamId}

Fetch a single team by ID.

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/teams/{teamId}"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "tm_w8z2q6t4m1x7c9v3b5n0k2j6",
    "name": "Marketing team",
    "avatarUrl": "https://example.com/avatar.png",
    "defaultPlatforms": [
      "twitter",
      "linkedin"
    ],
    "primaryPlatform": "twitter",
    "scheduleTimezone": "America/New_York",
    "scheduleSlots": [
      {
        "id": "slot-1",
        "day": "monday",
        "time": "09:00"
      }
    ],
    "settings": {}
  },
  "meta": {
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6"
  }
}
PATCH
/teams/{teamId}

Update a team name or avatar. Only provided fields change.

NameTypeRequiredDescription
namestringNoUpdated team name.
avatarUrlstringNoUpdated avatar URL, or null to clear.
curl -X PATCH \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Growth team"
}' \
  "https://contentrabbitai.com/api/public/v1/teams/{teamId}"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "tm_w8z2q6t4m1x7c9v3b5n0k2j6",
    "name": "Growth team",
    "avatarUrl": "https://example.com/avatar.png",
    "defaultPlatforms": [
      "twitter",
      "linkedin"
    ],
    "primaryPlatform": "twitter",
    "scheduleTimezone": "America/New_York",
    "scheduleSlots": [
      {
        "id": "slot-1",
        "day": "monday",
        "time": "09:00"
      }
    ],
    "settings": {}
  },
  "meta": {
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6"
  }
}
DELETE
/teams/{teamId}

Delete a team.

curl -X DELETE \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/teams/{teamId}"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "tm_w8z2q6t4m1x7c9v3b5n0k2j6",
    "deleted": true
  },
  "meta": {
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6"
  }
}
PATCH
/teams/{teamId}/settings

Update default platforms and team settings.

NameTypeRequiredDescription
defaultPlatformsstring[]NoDefault platforms for new posts. Each platform must be attached to the team.
primaryPlatformstringNoPrimary platform. Must be present in defaultPlatforms.
settingsobjectNoTeam settings object. Merged with existing settings.
curl -X PATCH \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "defaultPlatforms": [
    "twitter",
    "linkedin"
  ],
  "primaryPlatform": "twitter"
}' \
  "https://contentrabbitai.com/api/public/v1/teams/{teamId}/settings"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "defaultPlatforms": [
      "twitter",
      "linkedin"
    ],
    "primaryPlatform": "twitter",
    "settings": {}
  },
  "meta": {
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6"
  }
}
PATCH
/teams/{teamId}/schedule

Update the posting schedule for a team.

NameTypeRequiredDescription
scheduleTimezonestringNoTimezone for the posting schedule.
scheduleSlotsobject[]NoPosting slots. Each slot must include id, day, and time.
curl -X PATCH \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "scheduleTimezone": "America/New_York",
  "scheduleSlots": [
    {
      "id": "slot-1",
      "day": "monday",
      "time": "09:00"
    }
  ]
}' \
  "https://contentrabbitai.com/api/public/v1/teams/{teamId}/schedule"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "scheduleTimezone": "America/New_York",
    "scheduleSlots": [
      {
        "id": "slot-1",
        "day": "monday",
        "time": "09:00"
      }
    ]
  },
  "meta": {
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6"
  }
}
GET
/teams/{teamId}/accounts

List accounts attached to a team.

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/teams/{teamId}/accounts"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": [
    {
      "id": "int_h8w2q5t9m4x7z1c6v3b0n5k2",
      "platformType": "twitter",
      "name": "@contentrabbit",
      "status": "active",
      "profileImageUrl": "https://cdn.example.com/avatars/contentrabbit.png"
    }
  ],
  "meta": {
    "count": 1,
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6"
  }
}
POST
/teams/{teamId}/accounts

Attach an integration to a team. Team owner only.

NameTypeRequiredDescription
integrationIdstringYesID of the integration to attach.
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "integrationId": "int_123"
}' \
  "https://contentrabbitai.com/api/public/v1/teams/{teamId}/accounts"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6",
    "integrationId": "int_123"
  },
  "meta": {
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6"
  }
}
DELETE
/teams/{teamId}/accounts

Detach an integration from a team. Team owner only.

NameTypeRequiredDescription
integrationIdstringYesID of the integration to detach.
curl -X DELETE \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/teams/{teamId}/accounts"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6",
    "integrationId": "int_123",
    "detached": true
  },
  "meta": {
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6"
  }
}
GET
/teams/{teamId}/members

List members of a team.

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/teams/{teamId}/members"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": [
    {
      "userId": "user_123",
      "roleId": "member",
      "email": "jane@example.com",
      "name": "Jane Doe"
    }
  ],
  "meta": {
    "count": 1,
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6"
  }
}
POST
/teams/{teamId}/members

Add a member to a team. Team owner only.

NameTypeRequiredDescription
userIdstringYesID of the user to add.
roleIdstringNoMember role. Defaults to member.
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "userId": "user_123",
  "roleId": "member"
}' \
  "https://contentrabbitai.com/api/public/v1/teams/{teamId}/members"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6",
    "userId": "user_123",
    "roleId": "member"
  },
  "meta": {
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6"
  }
}
DELETE
/teams/{teamId}/members/{userId}

Remove a member from a team. Team owner only.

curl -X DELETE \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/teams/{teamId}/members/{userId}"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6",
    "userId": "user_123",
    "deleted": true
  },
  "meta": {
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6"
  }
}

Accounts

GET
/accounts

List social accounts connected to the team.

NameTypeRequiredDescription
platformstringNoFilter by platform type, for example twitter or linkedin.
curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/accounts"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": [
    {
      "id": "int_h8w2q5t9m4x7z1c6v3b0n5k2",
      "platformType": "twitter",
      "name": "@contentrabbit",
      "status": "active",
      "profileImageUrl": "https://cdn.example.com/avatars/contentrabbit.png"
    }
  ],
  "meta": {
    "count": 1,
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6"
  }
}
GET
/accounts/{accountId}

Fetch a single connected account by ID.

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/accounts/{accountId}"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "int_h8w2q5t9m4x7z1c6v3b0n5k2",
    "platformType": "twitter",
    "name": "@contentrabbit",
    "status": "active",
    "profileImageUrl": "https://cdn.example.com/avatars/contentrabbit.png",
    "accessTokenExpiresAt": "2025-09-01T00:00:00.000Z",
    "createdAt": "2025-01-15T09:24:00.000Z"
  }
}
DELETE
/accounts/{accountId}

Disconnect an account from the team. Team owner only.

curl -X DELETE \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/accounts/{accountId}"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "int_h8w2q5t9m4x7z1c6v3b0n5k2",
    "disconnected": true
  }
}
GET
/accounts/{accountId}/health

Get connection health, token validity, and recommendations for an account.

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/accounts/{accountId}/health"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "int_h8w2q5t9m4x7z1c6v3b0n5k2",
    "platformType": "twitter",
    "status": "active",
    "tokenValid": true,
    "tokenExpiresAt": "2025-09-01T00:00:00.000Z",
    "recommendations": []
  }
}

Queue

GET
/queue/slots

List the schedule slots configured for the team.

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/queue/slots"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": [
    {
      "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "day": "monday",
      "time": "09:30"
    }
  ],
  "meta": {
    "count": 1,
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6"
  }
}
POST
/queue/slots

Add a schedule slot. Returns 409 when a slot with the same day and time exists.

NameTypeRequiredDescription
daystringYesDay of the week: monday, tuesday, wednesday, thursday, friday, saturday, or sunday.
timestringYesTime of day in HH:MM format (00:00-23:59).
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "day": "monday",
  "time": "09:30"
}' \
  "https://contentrabbitai.com/api/public/v1/queue/slots"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "day": "monday",
    "time": "09:30"
  },
  "meta": {
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6"
  }
}
PUT
/queue/slots/{slotId}

Update a schedule slot. Only provided fields change.

NameTypeRequiredDescription
daystringNoNew day of the week.
timestringNoNew time in HH:MM format (00:00-23:59).
curl -X PUT \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "day": "tuesday",
  "time": "15:00"
}' \
  "https://contentrabbitai.com/api/public/v1/queue/slots/{slotId}"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "day": "tuesday",
    "time": "15:00"
  },
  "meta": {
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6"
  }
}
DELETE
/queue/slots/{slotId}

Delete a schedule slot.

curl -X DELETE \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/queue/slots/{slotId}"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "deleted": true
  }
}
GET
/queue/next-slot

Get the next free schedule slot within the next 30 days.

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/queue/next-slot"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "day": "monday",
    "time": "09:30",
    "scheduledAt": "2025-06-02T13:30:00.000Z"
  }
}

Calendar

GET
/calendar

Get calendar entries grouped by day for a date range, with optional status filters.

NameTypeRequiredDescription
startdate-timeNoRange start. Defaults to 30 days before end.
enddate-timeNoRange end. Defaults to now.
timezonestringNoIANA timezone. Defaults to the team timezone.
statusstringNoFilter by status: scheduled, publishing, published, or error. Repeat the parameter for multiple values.
curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/calendar"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "timezone": "America/New_York",
    "range": {
      "start": "2025-05-02T04:00:00.000Z",
      "end": "2025-06-01T04:00:00.000Z"
    },
    "days": [
      {
        "date": "2025-06-01",
        "timezone": "America/New_York",
        "entries": [
          {
            "id": "post_p3k9m2x7q4t1w8z6c5v0b3n",
            "postId": "post_p3k9m2x7q4t1w8z6c5v0b3n",
            "status": "scheduled",
            "primaryPlatform": "twitter",
            "platforms": [
              "twitter",
              "linkedin"
            ],
            "scheduledAt": "2025-06-01T10:00:00.000Z",
            "publishedAt": null,
            "contentPreview": "Here is what we shipped this week...",
            "mediaCount": 1
          }
        ],
        "totals": {
          "scheduled": 1,
          "publishing": 0,
          "published": 0,
          "error": 0
        }
      }
    ],
    "scheduleSlots": [
      {
        "id": "slot-1",
        "day": "monday",
        "time": "09:00"
      }
    ]
  },
  "meta": {
    "range": {
      "start": "2025-05-02T04:00:00.000Z",
      "end": "2025-06-01T04:00:00.000Z"
    },
    "timezone": "America/New_York",
    "count": 1
  }
}

Webhooks

GET
/webhooks

List webhook subscriptions for the team.

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/webhooks"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": [
    {
      "id": "wh_t9q2w8m4x7z1c6v3b5n0k2j6",
      "targetUrl": "https://example.com/webhooks/content-rabbit",
      "description": "Production webhook",
      "eventTypes": [
        "post.published",
        "post.failed"
      ],
      "isActive": true,
      "createdAt": "2025-05-20T11:30:00.000Z",
      "updatedAt": "2025-05-20T11:30:00.000Z",
      "lastDeliveredAt": "2025-05-30T14:00:04.000Z",
      "secretPreview": "a1b2c3"
    }
  ],
  "meta": {
    "count": 1,
    "eventTypes": [
      "post.published",
      "post.failed",
      "scheduled.published",
      "scheduled.failed",
      "draft.updated",
      "media.uploaded",
      "credits.low",
      "account.connected",
      "account.disconnected"
    ]
  }
}
POST
/webhooks

Create a webhook subscription.

NameTypeRequiredDescription
targetUrlstringYesURL that receives webhook deliveries.
descriptionstringNoOptional label for the subscription, up to 255 characters.
eventTypesstring[]NoEvent types to subscribe to. Defaults to all event types.
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "targetUrl": "https://example.com/webhooks/content-rabbit",
  "description": "Production webhook",
  "eventTypes": [
    "post.published",
    "post.failed"
  ]
}' \
  "https://contentrabbitai.com/api/public/v1/webhooks"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "subscription": {
      "id": "wh_t9q2w8m4x7z1c6v3b5n0k2j6",
      "targetUrl": "https://example.com/webhooks/content-rabbit",
      "description": "Production webhook",
      "eventTypes": [
        "post.published",
        "post.failed"
      ],
      "isActive": true,
      "createdAt": "2025-05-20T11:30:00.000Z",
      "updatedAt": "2025-05-20T11:30:00.000Z",
      "lastDeliveredAt": null,
      "secretPreview": "a1b2c3"
    },
    "secret": "3d9f2c7a1b8e4f6d0c5a9b3e7f1d4c8a2b6e0f5d9c3a7b1e4f8d2c6a0b5e9f3d"
  }
}
DELETE
/webhooks

Delete a webhook subscription by query parameter.

NameTypeRequiredDescription
idstringYesQuery parameter. ID of the subscription to delete.
curl -X DELETE \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/webhooks"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "wh_t9q2w8m4x7z1c6v3b5n0k2j6",
    "deleted": true
  }
}
GET
/webhooks/{webhookId}

Fetch a single webhook subscription by ID.

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/webhooks/{webhookId}"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "wh_t9q2w8m4x7z1c6v3b5n0k2j6",
    "targetUrl": "https://example.com/webhooks/content-rabbit",
    "description": "Production webhook",
    "eventTypes": [
      "post.published",
      "post.failed"
    ],
    "isActive": true,
    "createdAt": "2025-05-20T11:30:00.000Z",
    "updatedAt": "2025-05-20T11:30:00.000Z",
    "lastDeliveredAt": "2025-05-30T14:00:04.000Z",
    "secretPreview": "a1b2c3"
  }
}
DELETE
/webhooks/{webhookId}

Delete a webhook subscription by ID.

curl -X DELETE \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/webhooks/{webhookId}"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "wh_t9q2w8m4x7z1c6v3b5n0k2j6",
    "deleted": true
  }
}
GET
/webhooks/deliveries

List webhook deliveries with optional filters.

NameTypeRequiredDescription
subscriptionIdstringNoFilter by subscription ID.
statusstringNoFilter by delivery status.
startdate-timeNoEarliest delivery time.
enddate-timeNoLatest delivery time.
limitintegerNoMaximum deliveries to return (up to 200).
curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/webhooks/deliveries"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "items": [
      {
        "id": "whd_c6v3b5n0k2j6t9q2w8m4x7z1",
        "subscriptionId": "wh_t9q2w8m4x7z1c6v3b5n0k2j6",
        "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6",
        "eventId": "x9k2m7v4q1t8w6z3c5b0n2j4",
        "eventType": "post.published",
        "status": "success",
        "attempts": 1,
        "nextAttemptAt": null,
        "occurredAt": "2025-05-30T14:00:04.000Z",
        "payload": {
          "postId": "post_p3k9m2x7q4t1w8z6c5v0b3n",
          "platform": "twitter",
          "postUrl": "https://twitter.com/contentrabbit/status/1798765432109876543"
        },
        "targetUrl": "https://example.com/webhooks/content-rabbit",
        "lastError": null,
        "signaturePreview": "a1b2c3"
      }
    ],
    "range": {
      "start": "2025-05-30T13:45:00.000Z",
      "end": "2025-05-30T14:00:00.000Z"
    }
  },
  "meta": {
    "count": 1,
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6"
  }
}
POST
/webhooks/test

Send a test delivery to a webhook subscription.

NameTypeRequiredDescription
webhookIdstringYesID of the subscription to send a test delivery to.
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "webhookId": "3f6b2a1c-9d4e-4c8b-a7f2-1e5d6c9b0a2f"
}' \
  "https://contentrabbitai.com/api/public/v1/webhooks/test"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "delivered": true,
    "statusCode": 200
  }
}

Generate

GET
/generate/text

List available text models with provider, capabilities, and pricing.

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/generate/text"

Response

{
  "data": [
    {
      "id": "openai/gpt-4.1-mini",
      "provider": "OpenAI",
      "capabilities": [
        "chat",
        "copywriting"
      ],
      "pricing": {
        "credits": 1,
        "usd": 0.01
      }
    }
  ],
  "meta": {
    "count": 1,
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6",
    "teamName": "Content Rabbit"
  }
}
POST
/generate/text

Generate text with a selected model. Extra body fields are forwarded to the model.

NameTypeRequiredDescription
modelstringYesText model ID. List valid IDs with GET /generate/text.
promptstringNoPrompt forwarded to the model.
previewbooleanNoWhen true, runs without charging credits.
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "openai/gpt-4.1-mini",
  "prompt": "Write a LinkedIn post about our API launch."
}' \
  "https://contentrabbitai.com/api/public/v1/generate/text"

Response

{
  "data": {
    "text": "Big launch day: our public API is live. Generate, schedule, and publish everywhere from one place."
  },
  "pricing": {
    "creditCost": 1,
    "usdValue": 0.01
  }
}
GET
/generate/image

List available image models with provider, capabilities, and pricing.

NameTypeRequiredDescription
mediaTypestringNoModel type to list: "image", "video", or "text". Defaults to "image".
curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/generate/image"

Response

{
  "data": [
    {
      "id": "replicate/black-forest-labs/flux-kontext-pro",
      "provider": "Replicate",
      "mediaType": "image",
      "capabilities": [
        "text-to-image"
      ],
      "pricing": {
        "credits": 9,
        "usd": 0.09
      }
    }
  ],
  "meta": {
    "count": 1,
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6",
    "teamName": "Content Rabbit"
  }
}
POST
/generate/image

Generate images with a selected model. Charges credits unless preview is true.

NameTypeRequiredDescription
modelstringYesImage model ID. List valid IDs with GET /generate/image.
promptstringYesText prompt that describes the image.
aspectstringNoAspect ratio such as "9:16" or "1:1". Use "auto" to derive one.
imagesintegerNoNumber of images to generate.
characterImageUrlstringNoReference image URL for character-consistent models.
previewbooleanNoWhen true, runs without charging credits.
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "replicate/black-forest-labs/flux-kontext-pro",
  "prompt": "Studio photo of a ceramic rabbit on a desk",
  "aspect": "1:1",
  "images": 1
}' \
  "https://contentrabbitai.com/api/public/v1/generate/image"

Response

{
  "data": {
    "success": true,
    "image": {
      "id": null,
      "url": "https://replicate.delivery/xezq/abc123/out-0.png",
      "thumbnailUrl": "https://replicate.delivery/xezq/abc123/out-0.png",
      "originalUrl": "https://replicate.delivery/xezq/abc123/out-0.png",
      "model": "replicate/black-forest-labs/flux-kontext-pro",
      "prompt": "Studio photo of a ceramic rabbit on a desk",
      "aspect": "1:1",
      "createdAt": "2025-05-28T16:50:00.000Z"
    }
  },
  "pricing": {
    "creditCost": 9,
    "usdValue": 0.09
  }
}
GET
/generate/video

List available video models with provider, capabilities, and pricing.

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/generate/video"

Response

{
  "data": [
    {
      "id": "minimax/hailuo-02/t2v-standard",
      "provider": "Minimax",
      "capabilities": [
        "text-to-video"
      ],
      "pricing": {
        "credits": 55,
        "usd": 0.55
      }
    }
  ],
  "meta": {
    "count": 1,
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6",
    "teamName": "Content Rabbit"
  }
}
POST
/generate/video

Generate a video with a selected model. Charges credits unless preview is true.

NameTypeRequiredDescription
modelstringYesVideo model ID. List valid IDs with GET /generate/video.
promptstringNoText prompt that describes the video.
durationnumberNoClip length in seconds. Billed per second on duration-priced models.
previewbooleanNoWhen true, runs without charging credits.
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "minimax/hailuo-02",
  "prompt": "Slow pan across a sunrise mountain ridge",
  "duration": 6
}' \
  "https://contentrabbitai.com/api/public/v1/generate/video"

Response

{
  "data": {
    "code": 200,
    "message": "success",
    "data": {
      "id": "9f8e7d6c-5b4a-3c2d-1e0f-a9b8c7d6e5f4",
      "model": "minimax/hailuo-02",
      "status": "created"
    }
  },
  "pricing": {
    "creditCost": 55,
    "usdValue": 0.55
  }
}
GET
/generate/jobs/{jobId}

Poll a generation job for its status, result, or error.

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/generate/jobs/{jobId}"

Response

{
  "data": {
    "id": "gen_x7z1c6v3b5n0k2j6t4w9q8m2",
    "status": "completed",
    "result": {
      "url": "https://cdn.example.com/generated/out-0.png"
    },
    "error": null,
    "createdAt": "2025-05-28T16:50:00.000Z",
    "updatedAt": "2025-05-28T16:50:09.000Z"
  }
}

Media

GET
/media/images

List images in the team with cursor-based pagination.

NameTypeRequiredDescription
searchstringNoSearch by title or filename.
limitintegerNoMaximum number of items to return (1-100). Defaults to 25.
cursorstringNoCursor from the previous page.
statusstringNoFilter by status: "active" or "deleted".
curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/media/images"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": [
    {
      "id": "img_k2j6n0b5v3c6z1x7m4t9q2w8",
      "title": "Launch hero image",
      "description": null,
      "altText": "Ceramic rabbit on a desk",
      "tags": [
        "launch",
        "hero"
      ],
      "sourceType": "upload",
      "sourceUrl": null,
      "attribution": null,
      "authorName": null,
      "authorUrl": null,
      "licenseType": "User Upload",
      "width": 1024,
      "height": 1024,
      "fileSize": 482113,
      "mimeType": "image/png",
      "url": "https://contentrabbitai.com/api/v1/images/serve?id=img_k2j6n0b5v3c6z1x7m4t9q2w8&variant=public",
      "thumbnailUrl": "https://contentrabbitai.com/api/v1/images/serve?id=img_k2j6n0b5v3c6z1x7m4t9q2w8&variant=thumbnail",
      "createdAt": "2025-05-28T16:40:00.000Z",
      "updatedAt": "2025-05-28T16:40:00.000Z"
    }
  ],
  "paging": {
    "nextCursor": "img_k2j6n0b5v3c6z1x7m4t9q2w8"
  },
  "filters": {}
}
POST
/media/images

Register an uploaded Cloudflare image in the team media library.

NameTypeRequiredDescription
cloudflareImageIdstringYesID returned by the upload-url flow after the file is uploaded.
titlestringNoImage title (max 200 characters).
descriptionstringNoImage description (max 2000 characters).
altTextstringNoAlt text for accessibility (max 500 characters).
tagsstring[]NoUp to 50 tags (max 50 characters each).
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "cloudflareImageId": "2cdc28f0-017a-49c4-9ed7-87056c839c2f",
  "title": "Launch hero image",
  "altText": "Ceramic rabbit on a desk",
  "tags": [
    "launch",
    "hero"
  ]
}' \
  "https://contentrabbitai.com/api/public/v1/media/images"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "img_k2j6n0b5v3c6z1x7m4t9q2w8",
    "title": "Launch hero image",
    "description": null,
    "altText": "Ceramic rabbit on a desk",
    "tags": [
      "launch",
      "hero"
    ],
    "sourceType": "upload",
    "sourceUrl": null,
    "attribution": null,
    "authorName": null,
    "authorUrl": null,
    "licenseType": "User Upload",
    "width": 1024,
    "height": 1024,
    "fileSize": 482113,
    "mimeType": "image/png",
    "url": "https://contentrabbitai.com/api/v1/images/serve?id=img_k2j6n0b5v3c6z1x7m4t9q2w8&variant=public",
    "thumbnailUrl": "https://contentrabbitai.com/api/v1/images/serve?id=img_k2j6n0b5v3c6z1x7m4t9q2w8&variant=thumbnail",
    "createdAt": "2025-05-28T16:40:00.000Z",
    "updatedAt": "2025-05-28T16:40:00.000Z"
  }
}
DELETE
/media/images/{imageId}

Delete an image from the team and from Cloudflare Images.

curl -X DELETE \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/media/images/{imageId}"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "img_k2j6n0b5v3c6z1x7m4t9q2w8",
    "deleted": true
  }
}
GET
/media/videos

List videos in the team with cursor-based pagination.

NameTypeRequiredDescription
searchstringNoSearch by title or filename.
limitintegerNoMaximum number of items to return (1-100). Defaults to 25.
cursorstringNoCursor from the previous page.
statusstringNoFilter by status: "active" or "deleted".
curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/media/videos"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": [
    {
      "id": "vid_t2w8q4m9x7z1c6v3b5n0k2j6",
      "title": "Product teaser",
      "description": null,
      "tags": [
        "teaser",
        "launch"
      ],
      "sourceType": "upload",
      "sourceUrl": null,
      "attribution": null,
      "authorName": null,
      "authorUrl": null,
      "licenseType": null,
      "width": 1080,
      "height": 1920,
      "duration": 12,
      "fileSize": 8451200,
      "mimeType": "video/mp4",
      "streamStatus": "ready",
      "playbackUrl": "https://contentrabbitai.com/api/v1/videos/vid_t2w8q4m9x7z1c6v3b5n0k2j6/public",
      "createdAt": "2025-05-28T16:45:00.000Z",
      "updatedAt": "2025-05-28T16:45:00.000Z"
    }
  ],
  "paging": {
    "nextCursor": "vid_t2w8q4m9x7z1c6v3b5n0k2j6"
  },
  "filters": {}
}
POST
/media/videos

Register an uploaded Cloudflare Stream video in the team media library.

NameTypeRequiredDescription
cloudflareStreamIdstringYesCloudflare Stream video ID to register.
titlestringNoVideo title (max 200 characters).
descriptionstringNoVideo description (max 2000 characters).
tagsstring[]NoUp to 50 tags (max 50 characters each).
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "cloudflareStreamId": "ea95132c15732412d22c1476fa83f27a",
  "title": "Product teaser",
  "tags": [
    "teaser",
    "launch"
  ]
}' \
  "https://contentrabbitai.com/api/public/v1/media/videos"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "vid_t2w8q4m9x7z1c6v3b5n0k2j6",
    "title": "Product teaser",
    "description": null,
    "tags": [
      "teaser",
      "launch"
    ],
    "sourceType": "upload",
    "sourceUrl": null,
    "attribution": null,
    "authorName": null,
    "authorUrl": null,
    "licenseType": null,
    "width": 1080,
    "height": 1920,
    "duration": 12,
    "fileSize": 8451200,
    "mimeType": "video/mp4",
    "streamStatus": "ready",
    "playbackUrl": "https://contentrabbitai.com/api/v1/videos/vid_t2w8q4m9x7z1c6v3b5n0k2j6/public",
    "createdAt": "2025-05-28T16:45:00.000Z",
    "updatedAt": "2025-05-28T16:45:00.000Z"
  }
}
POST
/media/upload-url

Create a signed Cloudflare Images upload URL for direct browser uploads.

NameTypeRequiredDescription
requireSignedbooleanNoRequire signed uploads. Defaults to true.
expirySecondsintegerNoSeconds until the upload URL expires (60-3600). Defaults to 600.
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "requireSigned": true,
  "expirySeconds": 600
}' \
  "https://contentrabbitai.com/api/public/v1/media/upload-url"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "uploadURL": "https://upload.imagedelivery.net/f4c2b8d1e6a94f3b9c7d5e2a1f8b6c4d",
    "id": "2cdc28f0-017a-49c4-9ed7-87056c839c2f",
    "expiresAt": "2025-05-28T17:00:00.000Z",
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6"
  }
}

Sources

POST
/sources

Create a content extraction job. "url" and "text" sources are live; "youtube", "pdf", and "audio" return an unsupported error for now.

NameTypeRequiredDescription
typestringYesSource type: "url", "text", "youtube", "pdf", or "audio".
valuestringYesThe URL to extract from, or the raw text content.
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "type": "url",
  "value": "https://example.com/blog/launch-notes"
}' \
  "https://contentrabbitai.com/api/public/v1/sources"

Response

{
  "jobId": "src_j6k2n9b4v8c3z1x5m7t0q2w6",
  "status": "queued"
}
GET
/sources/{jobId}

Poll an extraction job. Returns the extracted text when the status is completed.

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/sources/{jobId}"

Response

{
  "status": "completed",
  "result": {
    "text": "Extracted page content...",
    "title": "Launch notes",
    "metadata": {
      "sourceType": "url",
      "url": "https://example.com/blog/launch-notes",
      "contentType": "text/html; charset=utf-8"
    }
  }
}

Analytics

GET
/analytics/posts

Get aggregated post analytics for the team over a date range.

NameTypeRequiredDescription
startdate-timeNoRange start. Defaults to 30 days before end. Must be before end.
enddate-timeNoRange end. Defaults to now. Range is clamped to 365 days.
timezonestringNoIANA timezone for day boundaries. Defaults to the team timezone.
curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/analytics/posts"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6",
    "timezone": "America/New_York",
    "range": {
      "start": "2025-05-02T04:00:00.000Z",
      "end": "2025-06-01T04:00:00.000Z"
    },
    "totals": {
      "drafts": 3,
      "scheduled": 2,
      "publishing": 0,
      "published": 41,
      "failed": 1
    },
    "media": {
      "withMedia": 18,
      "withoutMedia": 29
    }
  },
  "meta": {
    "range": {
      "start": "2025-05-02T04:00:00.000Z",
      "end": "2025-06-01T04:00:00.000Z"
    },
    "timezone": "America/New_York"
  }
}
GET
/analytics/platforms

Get per-platform analytics for the team over a date range.

NameTypeRequiredDescription
platformstringNoFilter by platform (for example "twitter"). Repeat the parameter for several.
startdate-timeNoRange start. Defaults to 30 days before end. Must be before end.
enddate-timeNoRange end. Defaults to now. Range is clamped to 365 days.
timezonestringNoIANA timezone for day boundaries. Defaults to the team timezone.
curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/analytics/platforms"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "timezone": "America/New_York",
    "range": {
      "start": "2025-05-02T04:00:00.000Z",
      "end": "2025-06-01T04:00:00.000Z"
    },
    "platforms": [
      {
        "platform": "linkedin",
        "totals": {
          "drafts": 1,
          "scheduled": 1,
          "publishing": 0,
          "published": 20,
          "failed": 1
        },
        "nextScheduledAt": "2025-06-01T10:00:00.000Z",
        "lastPublishedAt": "2025-05-30T14:00:00.000Z"
      },
      {
        "platform": "twitter",
        "totals": {
          "drafts": 2,
          "scheduled": 1,
          "publishing": 0,
          "published": 21,
          "failed": 0
        },
        "nextScheduledAt": "2025-06-02T13:30:00.000Z",
        "lastPublishedAt": "2025-05-30T14:00:00.000Z"
      }
    ]
  },
  "meta": {
    "range": {
      "start": "2025-05-02T04:00:00.000Z",
      "end": "2025-06-01T04:00:00.000Z"
    },
    "timezone": "America/New_York",
    "count": 2
  }
}

Messages

GET
/conversations

List direct-message conversations (Instagram and Facebook) with cursor-based pagination.

NameTypeRequiredDescription
platformstringNoFilter by platform: "instagram" or "facebook".
accountIdstringNoFilter by connected account ID.
statusstringNoFilter by conversation status: "open" or "archived".
limitintegerNoMaximum number of items to return (1-100). Defaults to 25.
cursorstringNoCursor from the previous page.
curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/conversations"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": [
    {
      "id": "conv_m4t9q2w8k6j3n0b5v7c1z6x4",
      "teamId": "team_h3b7v1n5m9q3w7t1k5c9x3z7",
      "platform": "instagram",
      "accountId": "acc_w8z2q6t4m1x7c9v3b5n0k2j6",
      "status": "open",
      "participantHandle": "happy.customer",
      "participantName": "Happy Customer",
      "lastMessageAt": "2025-05-28T16:40:00.000Z",
      "unreadCount": 0,
      "createdAt": "2025-05-27T09:15:00.000Z",
      "updatedAt": "2025-05-28T16:40:00.000Z"
    }
  ],
  "paging": {
    "nextCursor": "conv_m4t9q2w8k6j3n0b5v7c1z6x4"
  }
}
GET
/conversations/{conversationId}

Fetch a single conversation by ID.

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/conversations/{conversationId}"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "conv_m4t9q2w8k6j3n0b5v7c1z6x4",
    "teamId": "team_h3b7v1n5m9q3w7t1k5c9x3z7",
    "platform": "instagram",
    "accountId": "acc_w8z2q6t4m1x7c9v3b5n0k2j6",
    "status": "open",
    "participantHandle": "happy.customer",
    "participantName": "Happy Customer",
    "lastMessageAt": "2025-05-28T16:40:00.000Z",
    "unreadCount": 0,
    "createdAt": "2025-05-27T09:15:00.000Z",
    "updatedAt": "2025-05-28T16:40:00.000Z"
  }
}
GET
/messages

List messages in a conversation with cursor-based pagination.

NameTypeRequiredDescription
conversationIdstringYesConversation whose messages to list.
limitintegerNoMaximum number of items to return (1-100). Defaults to 25.
cursorstringNoCursor from the previous page.
curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/messages"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": [
    {
      "id": "dmsg_q2w8k6j3n0b5v7c1z6x4m4t9",
      "conversationId": "conv_m4t9q2w8k6j3n0b5v7c1z6x4",
      "teamId": "team_h3b7v1n5m9q3w7t1k5c9x3z7",
      "externalMessageId": "m_1234567890",
      "direction": "outbound",
      "text": "Thanks for reaching out! Here is the link you asked for.",
      "attachments": [],
      "sentAt": "2025-05-28T16:40:00.000Z",
      "deliveryStatus": "sent",
      "createdAt": "2025-05-28T16:40:00.000Z"
    }
  ],
  "paging": {
    "nextCursor": "dmsg_q2w8k6j3n0b5v7c1z6x4m4t9"
  }
}
GET
/messages/{messageId}

Fetch a single message by ID.

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/messages/{messageId}"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "dmsg_q2w8k6j3n0b5v7c1z6x4m4t9",
    "conversationId": "conv_m4t9q2w8k6j3n0b5v7c1z6x4",
    "teamId": "team_h3b7v1n5m9q3w7t1k5c9x3z7",
    "externalMessageId": "m_1234567890",
    "direction": "outbound",
    "text": "Thanks for reaching out! Here is the link you asked for.",
    "attachments": [],
    "sentAt": "2025-05-28T16:40:00.000Z",
    "deliveryStatus": "sent",
    "createdAt": "2025-05-28T16:40:00.000Z"
  }
}
POST
/messages

Send a direct message or reply in an existing conversation.

NameTypeRequiredDescription
conversationIdstringNoConversation to reply in. Required unless platform, accountId, and recipient are provided to start a new conversation.
platformstringNoRequired with accountId and recipient to start a new conversation. One of "instagram" or "facebook".
accountIdstringNoRequired with platform and recipient to start a new conversation. Connected account to send from.
recipientstringNoRequired with platform and accountId to start a new conversation. External participant ID or handle to message.
textstringYesMessage text.
attachmentsobject[]NoOptional attachments to include with the message (max 1).
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "conversationId": "conv_m4t9q2w8k6j3n0b5v7c1z6x4",
  "text": "Thanks for reaching out! Here is the link you asked for."
}' \
  "https://contentrabbitai.com/api/public/v1/messages"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "dmsg_q2w8k6j3n0b5v7c1z6x4m4t9",
    "conversationId": "conv_m4t9q2w8k6j3n0b5v7c1z6x4",
    "teamId": "team_h3b7v1n5m9q3w7t1k5c9x3z7",
    "externalMessageId": "m_1234567890",
    "direction": "outbound",
    "text": "Thanks for reaching out! Here is the link you asked for.",
    "attachments": [],
    "sentAt": "2025-05-28T16:40:00.000Z",
    "deliveryStatus": "sent",
    "createdAt": "2025-05-28T16:40:00.000Z"
  }
}

Tools

POST
/tools/validate/post

Check post text against per-platform character limits before publishing.

NameTypeRequiredDescription
contentstringYesPost text to validate.
platformsstring[]YesPlatforms to validate the content against.
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "content": "Big news: we just launched our new scheduler.",
  "platforms": [
    "twitter",
    "linkedin"
  ]
}' \
  "https://contentrabbitai.com/api/public/v1/tools/validate/post"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "valid": true,
    "platforms": {
      "twitter": {
        "valid": true,
        "characterCount": 45,
        "characterLimit": 280,
        "errors": []
      },
      "linkedin": {
        "valid": true,
        "characterCount": 45,
        "characterLimit": 3000,
        "errors": []
      }
    }
  }
}
POST
/tools/validate/media

Check a media file against per-platform size and format rules.

NameTypeRequiredDescription
mediaTypestringYesMedia kind: "image" or "video".
platformsstring[]YesPlatforms to validate the media against.
fileSizenumberNoFile size in bytes.
mimeTypestringNoMIME type of the file, for example "image/png".
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "mediaType": "image",
  "platforms": [
    "instagram",
    "facebook"
  ],
  "fileSize": 2450000,
  "mimeType": "image/png"
}' \
  "https://contentrabbitai.com/api/public/v1/tools/validate/media"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "valid": false,
    "platforms": {
      "instagram": {
        "valid": false,
        "errors": [
          "instagram image does not support MIME image/png"
        ],
        "requirements": {
          "maxFileSize": 8388608,
          "allowedTypes": [
            "image/jpeg"
          ],
          "maxWidth": 1440
        }
      },
      "facebook": {
        "valid": true,
        "errors": [],
        "requirements": {
          "maxFileSize": 10485760,
          "allowedTypes": [
            "image/jpeg",
            "image/bmp",
            "image/png",
            "image/gif",
            "image/tiff"
          ]
        }
      }
    }
  }
}

Usage

GET
/usage

Get usage for the team: posts published this month, connected accounts, and per-platform publishing limits.

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/usage"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "teamId": "tm_w8z2q6t4m1x7c9v3b5n0k2j6",
    "postsThisMonth": 42,
    "postsLimit": null,
    "accountsConnected": 3,
    "accountsLimit": null,
    "storageUsedMB": 0,
    "platformLimits": {
      "twitter": {
        "limit": 80,
        "used": 12,
        "remaining": 68,
        "windowLabel": "15 minutes"
      },
      "linkedin": {
        "limit": 80,
        "used": 9,
        "remaining": 71,
        "windowLabel": "24 hours"
      }
    }
  }
}

Activity

GET
/activity

List the team activity feed for a date range with cursor-based pagination.

NameTypeRequiredDescription
startdate-timeNoRange start. Defaults to 14 days before end.
enddate-timeNoRange end. Defaults to now.
timezonestringNoIANA timezone. Defaults to the team timezone.
limitintegerNoNumber of items to return (1-200, default 50).
cursorstringNoCursor from the previous page.
curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/activity"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "timezone": "America/New_York",
    "range": {
      "start": "2025-05-18T04:00:00.000Z",
      "end": "2025-06-01T04:00:00.000Z"
    },
    "items": [
      {
        "id": "post_p3k9m2x7q4t1w8z6c5v0b3n:published:1748613600000",
        "postId": "post_p3k9m2x7q4t1w8z6c5v0b3n",
        "eventType": "draft.published",
        "platform": "linkedin",
        "occurredAt": "2025-05-30T14:00:00.000Z",
        "message": "Published successfully"
      },
      {
        "id": "post_p3k9m2x7q4t1w8z6c5v0b3n:scheduled:1748613600000",
        "postId": "post_p3k9m2x7q4t1w8z6c5v0b3n",
        "eventType": "draft.scheduled",
        "platform": "linkedin",
        "occurredAt": "2025-05-30T14:00:00.000Z",
        "message": "Scheduled for 2025-05-30T14:00:00.000Z (America/New_York)",
        "metadata": {
          "timezone": "America/New_York"
        }
      },
      {
        "id": "post_p3k9m2x7q4t1w8z6c5v0b3n:created",
        "postId": "post_p3k9m2x7q4t1w8z6c5v0b3n",
        "eventType": "draft.created",
        "platform": "linkedin",
        "occurredAt": "2025-05-28T16:40:00.000Z",
        "message": "Draft created for linkedin"
      }
    ],
    "pagination": {
      "cursor": "MjAyNS0wNS0yOFQxNjo0MDowMC4wMDBa",
      "hasMore": true
    }
  },
  "meta": {
    "count": 3,
    "cursor": "MjAyNS0wNS0yOFQxNjo0MDowMC4wMDBa"
  }
}

API Keys

GET
/api-keys

List API keys for the team. Key secrets are never returned.

NameTypeRequiredDescription
includeRevokedbooleanNoSet to true to include revoked keys in the response.
curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/api-keys"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": [
    {
      "id": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
      "name": "CI pipeline",
      "preview": "cr_x9k2...",
      "createdAt": "2025-04-12T09:00:00.000Z",
      "enabled": true,
      "revoked": false,
      "revokedAt": null
    }
  ],
  "meta": {
    "count": 1
  }
}
POST
/api-keys

Not implemented. Returns HTTP 501. Create API keys in the web dashboard.

curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/api-keys"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "error": "Not Implemented",
  "message": "Use the web dashboard to create API keys"
}
DELETE
/api-keys/{keyId}

Revoke an API key. The key stops working immediately.

curl -X DELETE \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://contentrabbitai.com/api/public/v1/api-keys/{keyId}"

Response

{
  "requestId": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
  "data": {
    "id": "key_v9k2m7x4q1t8w6z3c5b0n2j4",
    "revoked": true,
    "revokedAt": "2025-05-30T14:00:00.000Z"
  }
}
Was this helpful?