# LetsPost — Full Agent Guide > Agent-readable expansion of https://letspost.it/llms.txt. Inlines the > endpoint catalog, MCP tool roster, auth model, error envelope, idempotency > rules, and webhook policy in one document so an agent can read it once and > work the API without further crawling. Generated 2026-05-23. Counts and tool names verified against the live registry on this date. If anything below disagrees with `openapi.json`, trust `openapi.json`. --- ## 1. Identity - **Product:** LetsPost — social-media posting API + remote MCP server. - **Domain:** letspost.it (marketing & docs), api.letspost.it (REST), mcp.letspost.it (MCP), app.letspost.it (dashboard). - **Audience:** AI agents and developers who want to schedule/publish across 10+ social platforms from one API key. - **Platforms supported:** Instagram, TikTok, YouTube, X (Twitter), Threads, LinkedIn, Facebook, Pinterest, Bluesky, Mastodon, WhatsApp. ## 2. Authentication - Bearer API keys: `Authorization: Bearer lp_live_xxx`. - Create at https://letspost.it/api-keys (signed-in dashboard). - Three scope buckets: - `mcp:read` — list/get drafts, posts, analytics, schedule. - `mcp:write` — draft, preview, schedule jobs, brand kit, reviewers. - `mcp:publish` — anything that ships to social platforms. - Same key works for both REST and the MCP server. Scopes are enforced on both surfaces. - Optional `Idempotency-Key` header on writes — a duplicate retry within 24h returns the original response instead of creating a second resource. ## 3. Errors Every 4xx/5xx returns the envelope: ```json { "code": "post_not_found", "message": "No post with id=post_abc123", "request_id": "req_01H..." } ``` `code` is stable and machine-checkable. `message` is human-readable English. `request_id` is included on every response (header `x-request-id`) and helps support look up the failure. ## 4. Rate limits - Per-API-key bucket. Limits scale with plan tier. - On 429: response headers `x-ratelimit-limit`, `x-ratelimit-remaining`, `x-ratelimit-reset` (epoch seconds). - Backoff: full jitter, 1s → 2s → 4s → 8s → fail-fast. ## 5. REST endpoint catalog (high-value subset) Full list at https://api.letspost.it/v1/openapi.json. Highest-traffic routes: - `POST /v1/posts` — create a post (defaults to draft). Required: `profileId`, `content`, `platforms[]`. Optional: `mediaUrl`, `scheduledFor` (ISO 8601 UTC), `platformDescriptions` (per-platform caption override). - `POST /v1/posts/fanout` — create the same post across N platforms in one call (mirrors `commit_workspace(publish_now)` on MCP). - `POST /v1/posts/validate` — dry-run preview. Returns the per-platform payload that would be submitted and any rejection reasons (bad aspect ratio, missing media, etc.). - `GET /v1/posts` — list. Cursor-based pagination (`cursor`, `limit≤100`). Filter: `status`, `platform`, `scheduledAfter`, `scheduledBefore`. - `GET /v1/posts/:id` — full post detail, including per-platform results. - `PATCH /v1/posts/:id` — mutate caption, platforms, media, scheduledFor. Drafts only; published posts return `post_immutable`. - `DELETE /v1/posts/:id` — soft-delete with 30s undo window; pass `?permanent=true` to skip the window. - `GET /v1/posts/stats` — period summary (counts, top post). - `POST /v1/media/presign-upload` — returns a 15-minute signed PUT URL + storage path. Upload your bytes directly, then pass the path to `POST /v1/posts` as `mediaUrl`. - `GET /v1/connections/providers` — connected accounts + health (active / expired / revoked). - `POST /v1/connections/oauth-url` — start the OAuth dance for a platform; returns a deep link. - `GET /v1/billing/status` — current plan, quota counters, upcoming renewal. - `POST /v1/billing/portal` — Stripe-hosted billing portal URL. - `POST /v1/webhooks/stripe` — server-to-server only (HMAC-verified). - `POST /v1/whatsapp/webhooks` — Meta delivery & message webhooks (HMAC-verified). - `GET /v1/auth/me` — current user + tenant snapshot. ## 6. MCP tool roster (53 tools) Live registry source: `apps/backend/src/agent/mcp-server/mcp-tool-bridge.service.ts`. Per-tool descriptions: https://letspost.it/agents#mcp-tools. ### mcp:read (16) `check_schedule_conflict`, `find_post`, `get_brand_kit`, `get_connection_health`, `get_period_summary`, `get_post_details`, `get_top_post`, `get_user_status`, `list_drafts`, `list_jobs`, `list_post_versions`, `list_recent_posts`, `list_repost_sequences`, `list_reviewers`, `list_upcoming_scheduled`, `suggest_best_time`. ### mcp:write (33) `add_media_to_draft`, `add_platforms_to_post`, `add_reviewer`, `bulk_reschedule`, `cancel_draft`, `cancel_repost_sequence`, `create_post`, `crop_and_recompose`, `delete_job`, `fix_grammar`, `generate_publish_preview`, `open_support_ticket`, `pause_job`, `permanent_delete`, `presign_media_upload`, `preview_post_summary`, `remove_reviewer`, `request_review`, `resume_job`, `schedule_job`, `schedule_recurring`, `schedule_repost_sequence`, `set_brand_kit`, `set_default_platforms`, `set_default_schedule_slot`, `set_post_platforms`, `set_require_approval_default`, `set_workspace_schedule`, `start_connect`, `translate_caption`, `undo_last_action`, `update_job`, `update_post_caption`. ### mcp:publish (4) `commit_workspace`, `publish_post`, `retry_failed_platforms`, `schedule_post`. ## 7. Idempotency contract - Pass `Idempotency-Key: ` on POST/PATCH/DELETE. - Server stores the (key, request-fingerprint, response) tuple for 24h. - Retry with the same key + same body → returns the cached response. - Retry with the same key + different body → returns `idempotency_conflict`. ## 8. Webhook policy - Event types: `post.published`, `post.failed`, `post.scheduled`, `post.canceled`, `connection.expired`, `connection.revoked`, `billing.*`. - Signature: HMAC-SHA256 over the raw body with your endpoint secret; header `x-letspost-signature: t=,v1=`. - Verify within 5 minutes of `t` to defeat replay. - Retries: exponential backoff for 24h; deliveries dropped after. - Local testing: `cloudflared tunnel --url http://localhost:3000` and point the webhook URL at the tunnel. ## 9. Quickstart curl ```bash curl https://api.letspost.it/v1/posts \ -H "Authorization: Bearer lp_live_xxx" \ -H "Idempotency-Key: hello-letspost-001" \ -H "Content-Type: application/json" \ -d '{ "profileId": "prof_abc123", "content": "Hello from an agent.", "platforms": ["x"] }' ``` ## 10. MCP setup snippet (Claude Code) `~/.claude.json`: ```json { "mcpServers": { "letspost": { "type": "http", "url": "https://mcp.letspost.it/v1/mcp", "headers": { "Authorization": "Bearer lp_live_xxx" } } } } ``` Equivalent for Claude Desktop (`claude_desktop_config.json`) and Cursor (`~/.cursor/mcp.json`). ChatGPT Custom GPTs use OpenAPI Actions instead — import `https://api.letspost.it/v1/openapi.json` under Actions. ## 11. Data + security - AES-256 at rest. Per-tenant data isolation. Firebase Auth + Firebase Hosting on the marketing surface. - Stripe handles billing (PCI-DSS Level 1). - No card data ever touches LetsPost servers. ## 12. Support - Email: support@letspost.it. - Status & changelog: https://letspost.it/docs/changelog. - Docs index: https://letspost.it/docs.