# Relay > Relay schedules and publishes posts to Instagram. Everything the dashboard does is also > available to machines: a REST API under `/v1` for your own code, and an MCP server at `/mcp` > for AI agents. Both authenticate with the same API key. Instagram is the only platform Relay > publishes to today. Relay handles the parts of Instagram publishing that are tedious to build yourself: OAuth with token refresh, media hosting on public URLs, the container → poll → publish handshake, retries on transient errors, scheduling, and a per-account outcome you can read back with Instagram's own error code when something is rejected. Your API base URL and MCP endpoint are shown on the docs pages and in the dashboard under "API keys" and "MCP". Create a key at /keys — the value is shown once. ## Documentation - [Overview and quickstart](https://relay.lantean.tech/docs): core objects, publishing lifecycle, five-minute quickstart, limits - [REST API reference](https://relay.lantean.tech/docs/api): endpoints, auth, idempotency, pagination, errors, object reference - [MCP server](https://relay.lantean.tech/docs/mcp): endpoint, client setup, tool reference, behavior annotations, agent workflow - [Instagram requirements](https://relay.lantean.tech/docs/instagram): account types, media specs, publishing quota, failure codes ## REST quick reference Base: `/v1` · Auth: `Authorization: Bearer rly_live_…` · JSON in, JSON out. - `GET /v1/accounts` — connected accounts with status, token expiry, follower counts (camelCase fields) - `POST /v1/posts` — create and queue a post. Body: `targets` (account ID array, required), `caption` (1–2200 chars, required), `media` (up to 10 media IDs or public URLs), `post_type` (`feed` | `carousel` | `reel` | `story`, inferred when omitted), `share_to_feed` (reels only), `schedule_at` (ISO 8601; omit to publish now). Returns 201. - `GET /v1/posts?status=&limit=&cursor=` — list newest-first; read `next_cursor` for the next page - `GET /v1/posts/:id` — one post with per-account `targets[]`: status, `platform_post_id`, `permalink`, `error { code, message }` - `PATCH /v1/posts/:id` — edit `caption` and/or `schedule_at` on a draft or scheduled post - `DELETE /v1/posts/:id` — cancel a draft or scheduled post - `POST /v1/media` — body `{ "url": "https://…" }`; stores the file and returns a reusable media ID Headers: send `Idempotency-Key` on the two POSTs — successful responses replay for 24 hours and carry `Idempotency-Replayed: true`; failed responses are not cached, so a fixed request can reuse the key. Rate limit is 120 requests/minute per key; over-limit gets `429` with `Retry-After`. Errors: domain errors are `{ "error": "message" }` with status 400/401/404. Schema-validation failures return `{ "success": false, "error": { "name": "ZodError", "message": "" } }`. Publish-time failures are never HTTP errors — they land on `targets[].error` and must be polled. ## MCP quick reference Endpoint: `/mcp` · Transport: streamable HTTP, stateless (no session ID) · Auth: `Authorization: Bearer rly_live_…`. Every tool declares an input and an output schema and returns `structuredContent` alongside the text block. - `auth_status` — verify the key, list authorized accounts (read-only) - `accounts_list` — accounts with health, token expiry, follower counts (read-only) - `post_create` — create/schedule a post across accounts (writes, open-world, NOT idempotent) - `post_status` — one post with its per-account delivery outcome (read-only) - `post_update` — edit caption and/or schedule of an unpublished post (writes, idempotent) - `post_cancel` — cancel a draft or scheduled post (writes, destructive) - `posts_list` — list posts with optional status filter and cursor (read-only) - `media_upload` — store a public URL and get a reusable media ID (writes, open-world) Working order: `auth_status` → `accounts_list` → (`media_upload`) → `post_create` → `post_status`. Never guess account or post IDs. `post_create` returns as soon as the post is queued; poll `post_status` for the outcome. Add to Claude Code: ``` claude mcp add --transport http relay /mcp \ --header "Authorization: Bearer $RELAY_API_KEY" ``` ## Limits - 120 API requests / minute per key; 30 failed auth attempts / minute per IP - 100 Instagram-published posts per account per rolling 24 hours (a carousel counts as one) - Caption 1–2,200 characters; carousel 2–10 items - Images: JPEG only, ≤ 8 MB, aspect ratio 4:5 – 1.91:1 for feed and carousel - Video: MP4 or MOV, ≤ 100 MB - Scheduler granularity ~60 seconds; "publish now" means the next tick - Idempotency replay window 24 hours ## Not supported PNG or non-JPEG images; text-only posts; filters, shopping tags, and product tagging; editing or deleting an already-published post; changing media or targets on an existing post; webhooks (poll instead); TikTok publishing. ## Contact support@lantean.tech