# Agents
Source: https://docs.recoupable.dev/agents
Programmatic agent onboarding — sign up and obtain API keys in one call, no dashboard, no human in the loop.
## Quickest start
Get a working API key in a single unauthenticated request:
```bash theme={null}
curl -X POST "https://api.recoupable.dev/api/agents/signup" \
-H "Content-Type: application/json" \
-d '{"email": "agent+'$(date +%s)-$RANDOM'@recoupable.com"}'
```
Response:
```json theme={null}
{
"account_id": "123e4567-e89b-12d3-a456-426614174000",
"api_key": "recoup_sk_abc123...",
"message": "If this is a new agent+ email, your API key is included. Otherwise, check your email for a verification code."
}
```
That's it. Store `api_key`, pass it in the `x-api-key` header on every subsequent request, and you're done.
**One-liner — sign up and export the key in one shot.** Drop this into your shell and you'll have `$RECOUP_API_KEY` ready to use on the next line:
```bash theme={null}
export RECOUP_API_KEY=$(curl -s -X POST "https://api.recoupable.dev/api/agents/signup" \
-H "Content-Type: application/json" \
-d '{"email": "agent+'$(date +%s)-$RANDOM'@recoupable.com"}' | jq -r .api_key)
```
Verify it worked:
```bash theme={null}
curl -H "x-api-key: $RECOUP_API_KEY" https://api.recoupable.dev/api/accounts/id
```
The `agent+{unique-suffix}@recoupable.com` shape is the recommended path for agents — it always returns an API key instantly, with no email verification required. Combining `$(date +%s)` with `$RANDOM` guarantees a fresh, collision-free address on every call (including multiple signups within the same second) and is portable across macOS and Linux shells.
## How it works
Two unauthenticated endpoints power agent onboarding:
* **[`POST /api/agents/signup`](/api-reference/agents/signup)** — Register with an email address. Emails with the `agent+` prefix that have never been seen before receive an API key immediately. Any other email (or a previously-used `agent+` address) receives a 6-digit verification code via email.
* **[`POST /api/agents/verify`](/api-reference/agents/verify)** — Submit the verification code to receive an API key.
Multiple API keys per account are supported — each signup or verification generates a new key without revoking existing ones.
## Standard signup (email verification)
If you're building a human-facing integration and want the user to verify their real email, use any non-`agent+` address:
Step 1 — request a verification code:
```bash theme={null}
curl -X POST "https://api.recoupable.dev/api/agents/signup" \
-H "Content-Type: application/json" \
-d '{"email": "you@example.com"}'
```
Step 2 — submit the 6-digit code from the verification email:
```bash theme={null}
curl -X POST "https://api.recoupable.dev/api/agents/verify" \
-H "Content-Type: application/json" \
-d '{"email": "you@example.com", "code": "123456"}'
```
Response:
```json theme={null}
{
"account_id": "123e4567-e89b-12d3-a456-426614174000",
"api_key": "recoup_sk_abc123...",
"message": "Verified"
}
```
## Using your API key
Pass the returned `api_key` in the `x-api-key` header on every authenticated request:
```bash theme={null}
curl -X GET "https://api.recoupable.dev/api/tasks" \
-H "x-api-key: YOUR_API_KEY"
```
See [Authentication](/authentication) for the full authentication model, including organization access and Bearer token support, and [Quickstart](/quickstart) for your first end-to-end request.
# Add Artist to Account
Source: https://docs.recoupable.dev/api-reference/accounts/add-artist
api-reference/openapi/accounts.json POST /api/accounts/artists
Add an artist to an account's list of associated artists. If the artist is already associated with the account, returns success without modification.
# Get Auto Top-Up Setting
Source: https://docs.recoupable.dev/api-reference/accounts/auto-recharge-get
api-reference/openapi/accounts.json GET /api/accounts/{id}/auto-recharge
Retrieve whether automatic top-up is enabled for the account.
# Update Auto Top-Up Setting
Source: https://docs.recoupable.dev/api-reference/accounts/auto-recharge-update
api-reference/openapi/accounts.json PATCH /api/accounts/{id}/auto-recharge
Enable or disable automatic top-up for the account.
# Create Account
Source: https://docs.recoupable.dev/api-reference/accounts/create
api-reference/openapi/accounts.json POST /api/accounts
Create a new account or retrieve an existing account by email or wallet address. If an account with the provided email or wallet already exists, returns that account. Otherwise creates a new account and initializes credits.
# Get Account Credits
Source: https://docs.recoupable.dev/api-reference/accounts/credits-get
api-reference/openapi/accounts.json GET /api/accounts/{id}/credits
Retrieve the current credit balance for an account. Returns the remaining credits along with the plan-derived monthly total and used count, plus a flag indicating whether the account is on a pro plan (directly or via an organization). Credits refill monthly; the `timestamp` field reflects the last refill or balance update.
# Get Account
Source: https://docs.recoupable.dev/api-reference/accounts/get
api-reference/openapi/accounts.json GET /api/accounts/{id}
Retrieve detailed account information by ID. Returns the account with associated profile info, emails, and wallet addresses.
# Get Account ID
Source: https://docs.recoupable.dev/api-reference/accounts/id
api-reference/openapi/accounts.json GET /api/accounts/id
Retrieve the ID of the authenticated account associated with the provided credentials. This is useful when you have an API key or access token but do not yet know the corresponding accountId.
# Get Default Payment Method
Source: https://docs.recoupable.dev/api-reference/accounts/payment-method-get
api-reference/openapi/accounts.json GET /api/accounts/{id}/payment-method
Retrieve the default payment method on file for an account. Returns `card: null` when no payment method has been saved yet — the top-up dialog uses this to decide whether to show a pre-charge confirmation (card present) or route to a checkout session to collect one (`card: null`). Cards are returned even when expired; callers should compare `exp_month` / `exp_year` against the current date and warn the customer, since an off-session charge against an expired card will decline.
# Get Account Subscription
Source: https://docs.recoupable.dev/api-reference/accounts/subscription-get
api-reference/openapi/accounts.json GET /api/accounts/{id}/subscription
Retrieve the subscription for an account, directly or via an organization.
# Update Account
Source: https://docs.recoupable.dev/api-reference/accounts/update
api-reference/openapi/accounts.json PATCH /api/accounts
Update an existing account's profile information including name, organization, image, instruction, job title, role type, company name, and knowledges. Requires authentication via x-api-key or Authorization Bearer token. The authenticated account may update itself or a permitted account_id override.
# List Agent Sign-Ups (Admin)
Source: https://docs.recoupable.dev/api-reference/admins/agent-signups
api-reference/openapi/accounts.json GET /api/admins/agent/signups
Returns API key sign-up records created by AI agents. Agent sign-ups are identified by the agent+ email prefix in the associated account email. Supports period filtering and returns individual API key records with their associated email and creation timestamp, suitable for building sign-up trend charts. Requires admin authentication.
# List Pro Artists (Admin)
Source: https://docs.recoupable.dev/api-reference/admins/artists-pro
api-reference/openapi/accounts.json GET /api/admins/artists/pro
Retrieve the deduplicated list of artist IDs owned by pro accounts. An account is "pro" when its email belongs to an enterprise domain or it has an active Stripe subscription. Admin-scoped: requires an admin-flagged API key because the response identifies paying customer accounts.
# Check Admin Status
Source: https://docs.recoupable.dev/api-reference/admins/check
api-reference/openapi/accounts.json GET /api/admins
Check if the authenticated account is a Recoup admin. An account is considered an admin if it is a member of the Recoup organization. No input parameters required — authentication is performed via the x-api-key or Authorization header.
# List Coding Agent Slack Tags (Admin)
Source: https://docs.recoupable.dev/api-reference/admins/coding-agent-slack-tags
api-reference/openapi/accounts.json GET /api/admins/coding/slack
Returns a list of Slack mentions of the Recoup Coding Agent bot, pulled directly from the Slack API as the source of truth. Each entry includes the tagger's information, the prompt they sent, the timestamp, the channel, and any GitHub pull request URLs opened in response. Also returns aggregate pull request statistics. Supports optional time-period filtering. Requires the authenticated account to be a Recoup admin. Authentication via x-api-key or Authorization Bearer token.
# Get Coding Agent PR Merged Status (Admin)
Source: https://docs.recoupable.dev/api-reference/admins/coding-pr
api-reference/openapi/accounts.json GET /api/admins/coding/pr
Returns the status (open, closed, or merged) for each provided GitHub pull request URL. Accepts one or more `pull_requests` query parameters containing GitHub PR URLs. Uses the GitHub REST API to check each pull request's state. Requires the authenticated account to be a Recoup admin. Authentication via x-api-key or Authorization Bearer token.
# List Content Agent Slack Tags (Admin)
Source: https://docs.recoupable.dev/api-reference/admins/content-slack-tags
api-reference/openapi/accounts.json GET /api/admins/content/slack
Returns a list of Slack mentions of the Recoup Content Agent bot, pulled directly from the Slack API as the source of truth. Each entry includes the tagger's information, the prompt they sent, the timestamp, the channel, and any video link responses. Also returns aggregate video statistics for measuring tag-to-video conversion. Supports optional time-period filtering. Requires the authenticated account to be a Recoup admin. Authentication via x-api-key or Authorization Bearer token.
# Credit Usage Events (Admin)
Source: https://docs.recoupable.dev/api-reference/admins/credits-events
api-reference/openapi/accounts.json GET /api/admins/credits/events
Returns the raw `usage_events` rows for a single account over the selected period, sorted by `created_at` descending. Powers the drilldown view that expands when a row in the [`/api/admins/credits/rollup`](/api-reference/admins/credits-rollup) table is opened. Each event represents one debit (main agent turn, subagent step, chat completion, or research call), with token counts and `credits_deducted_cents` matching the wallet drop on `credits_usage` for that account. Requires the authenticated account to be a Recoup admin.
# Credit Usage Rollup (Admin)
Source: https://docs.recoupable.dev/api-reference/admins/credits-rollup
api-reference/openapi/accounts.json GET /api/admins/credits/rollup
Returns the per-account rollup of credit usage over the selected period, sorted by total credits deducted descending. Each row carries the account identity (UUID + display name + primary email) and the aggregated spend so the admin dashboard can render a top-spenders table without joining client-side. Pair with [`GET /api/admins/credits/events?account_id=…&period=…`](/api-reference/admins/credits-events) to drill into the individual `usage_events` rows for a single account. Requires the authenticated account to be a Recoup admin.
# List Account Emails (Admin)
Source: https://docs.recoupable.dev/api-reference/admins/emails
api-reference/openapi/accounts.json GET /api/admins/emails
Returns Resend emails including HTML content. Provide either account_id (returns all emails for an account) or email_id (returns a single email by Resend ID). Requires the authenticated account to be a Recoup admin. Authentication via x-api-key or Authorization Bearer token. Email response shape matches the [Resend Retrieve Email API](https://resend.com/docs/api-reference/emails/retrieve-email).
# List Privy Logins (Admin)
Source: https://docs.recoupable.dev/api-reference/admins/privy
api-reference/openapi/accounts.json GET /api/admins/privy
Returns Privy login statistics for a given time period. Results include counts for new accounts (created_at), active accounts (latest_verified_at), total Privy accounts across all time, and the full, unmodified Privy account objects. See [Privy User object documentation](https://docs.privy.io/api-reference/users/get-all) for the complete type definition. Defaults to period=all (no date filter). Requires the authenticated account to be a Recoup admin. Authentication via x-api-key or Authorization Bearer token.
# List Account Sandboxes (Admin)
Source: https://docs.recoupable.dev/api-reference/admins/sandboxes
api-reference/openapi/accounts.json GET /api/admins/sandboxes
Returns a list of all accounts and their sandbox usage statistics. Each item includes the account email, total number of sandboxes created, and the timestamp of the most recently created sandbox. Requires the authenticated account to be a Recoup admin. Authentication via x-api-key or Authorization Bearer token.
# List Org Repo Stats (Admin)
Source: https://docs.recoupable.dev/api-reference/admins/sandboxes-orgs
api-reference/openapi/accounts.json GET /api/admins/sandboxes/orgs
Returns commit statistics for each repository in the recoupable GitHub organization. Each item includes the repo name, URL, total commit count, latest 5 commit messages, earliest and latest commit timestamps, and the list of account repo URLs that include this org repo as a submodule. Requires the authenticated account to be a Recoup admin. Authentication via x-api-key or Authorization Bearer token.
# Agent Signup
Source: https://docs.recoupable.dev/api-reference/agents/signup
api-reference/openapi/accounts.json POST /api/agents/signup
Register an agent. For new agent+ emails, returns an API key immediately. For all other cases, sends a verification code to the email — call [POST /api/agents/verify](/api-reference/agents/verify) with the code to get your API key.
**Tip:** If you're unsure what email to register, generate a unique `agent+{suffix}@recoupable.com` address (e.g. `agent+1744410896-28439@recoupable.com`, combining a Unix timestamp with a random integer). This guarantees a fresh `agent+` address on every call — including multiple signups within the same second — and returns an API key instantly with no email verification required.
# Verify Agent Email
Source: https://docs.recoupable.dev/api-reference/agents/verify
api-reference/openapi/accounts.json POST /api/agents/verify
Verify an agent's email with the code sent during signup. Returns an API key on success.
# List Models
Source: https://docs.recoupable.dev/api-reference/ai/models
api-reference/openapi/ai.json GET /api/ai/models
Returns the catalog of language models available through the Vercel AI Gateway. Embedding models are filtered out. The full schema mirrors the Vercel AI Gateway response (`GatewayLanguageModelEntry` from `@ai-sdk/gateway`); the documented properties below are the load-bearing fields used by clients. No authentication required.
# Scraper Results
Source: https://docs.recoupable.dev/api-reference/apify/scraper
api-reference/openapi/social.json GET /api/apify/runs/{runId}
Check the status and retrieve results from Apify scraper runs. This endpoint uses the Apify API Client to fetch the current status of a scraper run and its results if available. Use the runId returned from endpoints like Instagram Comments, Instagram Profiles, Social Scrape, or Artist Socials Scrape to poll for results.
# Socials scrape
Source: https://docs.recoupable.dev/api-reference/artist/socials-scrape
post /api/artist/socials/scrape
Trigger scrape jobs for all social profiles linked to an artist. Returns a runId per social profile that you can poll for status and results via the [Scraper Results API](/api-reference/apify/scraper).
# Create Artist
Source: https://docs.recoupable.dev/api-reference/artists/create
api-reference/openapi/releases.json POST /api/artists
Create a new artist account. The artist can optionally be linked to an organization.
# Delete Artist
Source: https://docs.recoupable.dev/api-reference/artists/delete
api-reference/openapi/releases.json DELETE /api/artists/{id}
Delete an artist accessible to the authenticated account.
# Get Artists
Source: https://docs.recoupable.dev/api-reference/artists/list
api-reference/openapi/releases.json GET /api/artists
Retrieve artists accessible to the authenticated account. The account is derived from the API key or Bearer token. When org_id is omitted, returns only the account's own artists. Pass org_id to view artists in a specific organization. Pass account_id to filter to a specific account the API key has access to.
# Pin Artist
Source: https://docs.recoupable.dev/api-reference/artists/pin
api-reference/openapi/releases.json POST /api/artists/{id}/pin
Pin an artist. This updates the caller's pinned preference for the artist.
# Get Artist Socials
Source: https://docs.recoupable.dev/api-reference/artists/socials
api-reference/openapi/releases.json GET /api/artists/{id}/socials
Retrieve all social media profiles associated with an artist. This endpoint should be called before using the Social Posts endpoint to obtain the necessary social IDs.
# Unpin Artist
Source: https://docs.recoupable.dev/api-reference/artists/unpin
api-reference/openapi/releases.json DELETE /api/artists/{id}/pin
Unpin an artist. This updates the caller's pinned preference for the artist.
# Update Artist
Source: https://docs.recoupable.dev/api-reference/artists/update
api-reference/openapi/releases.json PATCH /api/artists/{id}
Update an artist. All body fields are optional, but at least one must be provided. Use this endpoint to set basic profile (name, image, label), AI instructions, knowledge base entries, social profile URLs (mapped by platform), and pinned state for the calling account.
# Get Chat Artist
Source: https://docs.recoupable.dev/api-reference/chat/artist
api-reference/openapi/research.json GET /api/chats/{id}/artist
Retrieve the artist associated with a specific chat room. Returns 404 if the chat does not exist or is not accessible by the authenticated caller.
# Get Chats
Source: https://docs.recoupable.dev/api-reference/chat/chats
api-reference/openapi/research.json GET /api/chats
Returns chats for the authenticated account. Personal Bearer tokens see only the caller's chats; org keys see chats across the org's member accounts; admin keys see all chats. Each row carries the chat id and the session id needed to build the chat URL.
# Compact Chats
Source: https://docs.recoupable.dev/api-reference/chat/compact
api-reference/openapi/research.json POST /api/chats/compact
Compact one or more chat conversations into summarized versions. This reduces the size of chat history while preserving key information. Optionally provide a prompt to control what information gets preserved in the compacted summary.
# Create Chat
Source: https://docs.recoupable.dev/api-reference/chat/create
post /api/chats
Create a new chat room. Optionally associate it with an artist and/or provide a client-generated chat ID. Pass accountId to create a chat on behalf of a specific account the API key has access to.
# Delete Chat
Source: https://docs.recoupable.dev/api-reference/chat/delete
delete /api/chats
Delete a chat room by ID. This operation also removes related room records (memory emails, memories) before deleting the room itself.
# Get Chat Messages
Source: https://docs.recoupable.dev/api-reference/chat/messages
api-reference/openapi/research.json GET /api/chats/{id}/messages
Retrieve all messages (memories) for a specific chat room in chronological order.
# Copy Chat Messages
Source: https://docs.recoupable.dev/api-reference/chat/messages-copy
api-reference/openapi/research.json POST /api/chats/{id}/messages/copy
Copy all messages from the source chat (`id` path param) to a target chat (`targetChatId` in request body). By default, existing target messages are cleared before copy.
# Delete Trailing Chat Messages
Source: https://docs.recoupable.dev/api-reference/chat/messages-trailing-delete
api-reference/openapi/research.json DELETE /api/chats/{id}/messages/trailing
Delete all messages in a chat from a given message onward (inclusive), identified by `from_message_id`.
# Start Chat Run
Source: https://docs.recoupable.dev/api-reference/chat/runs
post /api/chat/runs
Start an asynchronous, headless chat-generation run on the durable agent workflow — the same engine as interactive [`POST /api/chat`](/api-reference/chat/workflow).
**Related endpoints**
- [`POST /api/chat`](/api-reference/chat/workflow) — use that for **interactive, streaming** turns on an existing chat; use this for **headless/programmatic** runs (no browser or pre-provisioned session needed).
- [`GET /api/chat/runs/{runId}`](/api-reference/chat/runs-status) — poll to learn **whether** the run finished (and if it succeeded).
- [`GET /api/chat/{chatId}/stream`](/api-reference/chat/workflow-stream) — **watch the output live** by passing the returned `chatId`.
# Get Chat Run Status
Source: https://docs.recoupable.dev/api-reference/chat/runs-status
get /api/chat/runs/{runId}
Status of an asynchronous run started via [`POST /api/chat/runs`](/api-reference/chat/runs). Returns a point-in-time snapshot (**is it done?**) — not the generated content.
**Related endpoints**
- [`POST /api/chat/runs`](/api-reference/chat/runs) — starts the run this reports on.
- [`GET /api/chat/{chatId}/stream`](/api-reference/chat/workflow-stream) — read the **content**: poll *this* to know **whether** a run finished; use the stream to **watch the output** as it's produced.
- [`POST /api/chat`](/api-reference/chat/workflow) — the interactive, streaming counterpart to a headless run.
# Stop Chat
Source: https://docs.recoupable.dev/api-reference/chat/stop
post /api/chat/{chatId}/stop
Stop the response currently being generated for a chat, freeing it to accept a new message. Idempotent — returns `stopped: false` when nothing is in progress. The chat must belong to the authenticated account.
# Update Chat
Source: https://docs.recoupable.dev/api-reference/chat/update
patch /api/chats
Update a chat room's topic (display name). The chatId is required; the topic field will be updated. Topic must be between 3 and 50 characters.
# Stream Chat
Source: https://docs.recoupable.dev/api-reference/chat/workflow
POST /api/chat
Streams an agent loop running as a durable [Vercel Workflow](https://vercel.com/docs/workflow) against the session's sandbox. The agent uses sandbox-only tools (`bash`, `read`, `write`, `grep`, `glob`, `todo`, `task`, `ask_user_question`, `skill`, `fetch`) — no MCP or Composio. Requires a sandbox provisioned via [`POST /api/sandbox`](/api-reference/sandbox/create).
**Related endpoints**
- [`POST /api/chat/runs`](/api-reference/chat/runs) — the **headless** counterpart: it provisions its own session + sandbox and runs without a streaming client. Use that for tasks/cron/programmatic runs; use this for **interactive, streaming** turns on an existing chat.
- [`GET /api/chat/{chatId}/stream`](/api-reference/chat/workflow-stream) — reconnect to an in-progress response.
- [`GET /api/chat/runs/{runId}`](/api-reference/chat/runs-status) — check **whether** a headless run finished (status, not content).
# Resume Chat Stream
Source: https://docs.recoupable.dev/api-reference/chat/workflow-stream
GET /api/chat/{chatId}/stream
Reconnects to an in-progress chat response — the resume counterpart to [`POST /api/chat`](/api-reference/chat/workflow), which never resumes. Returns the live Server-Sent Events stream when a response is still being generated, or `204 No Content` when there is nothing to resume. The chat must belong to the authenticated account.
**Related endpoints**
- [`POST /api/chat`](/api-reference/chat/workflow) — the interactive turn whose stream this resumes.
- [`POST /api/chat/runs`](/api-reference/chat/runs) — start a **headless** run, then pass the returned `chatId` here to **watch its output live**.
- [`GET /api/chat/runs/{runId}`](/api-reference/chat/runs-status) — check **whether** that run finished (status, not content).
# Get Comments
Source: https://docs.recoupable.dev/api-reference/comments/get
api-reference/openapi/social.json GET /api/comments
Retrieve comments associated with an artist or a specific post, with support for pagination. This endpoint returns raw comment data including the comment text, associated post, and commenter's social profile reference.
# Authorize Connector
Source: https://docs.recoupable.dev/api-reference/connectors/authorize
api-reference/openapi/social.json POST /api/connectors
Generate an OAuth authorization URL for connecting a third-party service. Redirect to the returned URL to complete the OAuth flow.
# Disconnect Connector
Source: https://docs.recoupable.dev/api-reference/connectors/disconnect
api-reference/openapi/social.json DELETE /api/connectors
Disconnect a connected account from a third-party service. This revokes the OAuth connection and removes stored credentials.
# Execute Connector Action
Source: https://docs.recoupable.dev/api-reference/connectors/execute-action
api-reference/openapi/social.json POST /api/connectors/actions
Execute a connector action with the given parameters. The `actionSlug` must come from a prior call to GET /api/connectors/actions, and `parameters` must match the `parameters` JSON Schema returned for that action. The action's parent connector must be currently connected (`isConnected: true` in the catalog) — otherwise this endpoint returns 409. The `result` field passes through whatever the underlying connector returns; its shape is action-specific. To attach an image to a `file_uploadable` parameter (e.g. `images`), first stage it with [Upload Connector File](/api-reference/connectors/upload-file) and pass the returned descriptor.
# List Connectors
Source: https://docs.recoupable.dev/api-reference/connectors/list
api-reference/openapi/social.json GET /api/connectors
List available connectors and their connection status. Returns all supported third-party integrations (e.g., Google Sheets, TikTok, YouTube, X (Twitter), LinkedIn) along with whether they are currently connected.
# List Connector Actions
Source: https://docs.recoupable.dev/api-reference/connectors/list-actions
api-reference/openapi/social.json GET /api/connectors/actions
List the executable actions available across the authenticated account's connectors. Each action is a single tool that can be invoked via POST /api/connectors/actions — for example, the `googlesheets` connector exposes actions like `GOOGLESHEETS_WRITE_SPREADSHEET`. Actions whose parent connector is not yet connected are returned with `isConnected: false` and cannot be executed until the connector is authorized via POST /api/connectors.
# Upload Connector File
Source: https://docs.recoupable.dev/api-reference/connectors/upload-file
api-reference/openapi/social.json POST /api/connectors/files
Stage an image into Connector file storage so it can be attached to a connector action that accepts a file_uploadable field. The returned descriptor is embedded in a file_uploadable array on [Execute Connector Action](/api-reference/connectors/execute-action).
# Task Callback
Source: https://docs.recoupable.dev/api-reference/content-agent/callback
api-reference/openapi/content.json POST /api/content-agent/callback
Internal callback endpoint for the `poll-content-run` Trigger.dev task. Receives content generation results and posts them back to the originating Slack thread. Authenticated via the `x-callback-secret` header.
This endpoint is not intended for external use — it is called automatically by the polling task when content runs complete, fail, or time out.
# Slack Webhook
Source: https://docs.recoupable.dev/api-reference/content-agent/webhook
api-reference/openapi/content.json POST /api/content-agent/{platform}
Webhook endpoint for the Recoup Content Agent Slack bot. Receives @mention events from Slack and triggers content generation for the mentioned artist. The bot parses the mention text for ` [template] [batch=N] [lipsync]`, validates the artist, calls POST /api/content/create, and starts a background polling task that reports results back to the Slack thread.
For Slack, also handles `url_verification` challenges during app setup.
# Analyze Video
Source: https://docs.recoupable.dev/api-reference/content/analyze-video
api-reference/openapi/content.json POST /api/content/analyze
Analyze a video and answer questions about it. Pass a video URL and a text prompt — for example, "Describe what happens" or "Rate the visual quality 1-10." Returns the generated text.
# Create Content
Source: https://docs.recoupable.dev/api-reference/content/create
api-reference/openapi/content.json POST /api/content/create
Trigger the content creation pipeline for an artist. Provide `artist_account_id` to identify the target artist. Validates the artist has all required files (face guide, songs) unless overridden via `songs` URLs or `images`, then triggers a background task that generates a short-form video. Returns `runIds` — an array of run IDs that can each be polled via [GET /api/tasks/runs](/api-reference/tasks/runs).
# Edit Content
Source: https://docs.recoupable.dev/api-reference/content/edit
api-reference/openapi/content.json PATCH /api/content
Apply ffmpeg edits to a video — trim, crop, resize, or overlay text. Pass a `template` for a preset edit pipeline, or build your own with an `operations` array.
# Estimate Cost
Source: https://docs.recoupable.dev/api-reference/content/estimate
api-reference/openapi/content.json GET /api/content/estimate
Estimate the cost of running the content creation pipeline. Calculates per-step and per-video costs based on current pricing. Supports comparing multiple workflow profiles (e.g., premium vs. budget) and projecting batch costs. This endpoint is informational only — it does not trigger any pipeline execution or spend credits.
# Generate Caption
Source: https://docs.recoupable.dev/api-reference/content/generate-caption
api-reference/openapi/content.json POST /api/content/caption
Generate a short caption from a topic. Returns the text content and default styling (font, color, size).
# Generate Image
Source: https://docs.recoupable.dev/api-reference/content/generate-image
api-reference/openapi/content.json POST /api/content/image
Generate an image from a text prompt. Pass a `reference_image_url` to guide the output toward a specific look or subject. Returns the image URL.
# Generate Video
Source: https://docs.recoupable.dev/api-reference/content/generate-video
api-reference/openapi/content.json POST /api/content/video
Generate a video. Set `mode` to control what kind of video you get:
- `prompt` — create a video from a text description
- `animate` — animate a still image
- `reference` — use an image as a style/subject reference (not the first frame)
- `extend` — continue an existing video
- `first-last` — generate a video that transitions between two images
- `lipsync` — sync face movement to an audio clip
If `mode` is omitted, it's inferred from the inputs you provide.
# Get Template Detail
Source: https://docs.recoupable.dev/api-reference/content/template-detail
api-reference/openapi/content.json GET /api/content/templates/{id}
Get the full configuration for a specific content creation template. Returns the complete creative recipe including image prompts, video motion config, caption style rules, and edit operations.
# List Templates
Source: https://docs.recoupable.dev/api-reference/content/templates
api-reference/openapi/content.json GET /api/content/templates
List all available content creation templates. Templates are optional — every content primitive works without one. When you do use a template, it provides a complete creative recipe: image prompts, video motion config, caption style rules, and edit operations. Returns template ID and description only — enough to pick the right one.
# Transcribe Audio
Source: https://docs.recoupable.dev/api-reference/content/transcribe-audio
api-reference/openapi/content.json POST /api/content/transcribe
Transcribe audio into text with word-level timestamps. Pass one or more audio file URLs in `audio_urls`. Returns the full transcript and an array of timed segments.
# Upscale Content
Source: https://docs.recoupable.dev/api-reference/content/upscale
api-reference/openapi/content.json POST /api/content/upscale
Upscale an image or video to higher resolution. Pass the URL and specify the type. Returns the upscaled URL.
# Validate Artist
Source: https://docs.recoupable.dev/api-reference/content/validate
api-reference/openapi/content.json GET /api/content/validate
Check whether an artist has all the required files to run the content creation pipeline. Returns a structured report of each required and recommended file with its status. Required files must be present or the pipeline will fail. Recommended files improve output quality but are not strictly necessary. Provide `artist_account_id` as a query parameter.
# Create Credits Top-Up Session
Source: https://docs.recoupable.dev/api-reference/credits/sessions-create
api-reference/openapi/accounts.json POST /api/credits/sessions
Top up credits on the authenticated account.
**One credit equals one US cent (\$0.01).** The customer is charged `credits` plus a Stripe processing fee (US card pricing: 2.9% + \$0.30) — e.g. `credits: 10000` charges \$103.30 total (\$100.00 credits + \$3.30 fee).
**Two outcomes, distinguished by response shape:**
- **Auto-charged** — if the account has a card on file (from a prior subscription or top-up), the card is charged immediately and the response is `{ paymentIntentId, creditsPurchased, totalCents }`. Credits land in the account's balance asynchronously via Stripe webhook (typically within seconds). No human interaction required.
- **Checkout required** — if no card is on file, or the saved card requires 3-D Secure authentication, the response is `{ id, url }` with a hosted Stripe Checkout URL. Redirect to that URL; credits land on successful payment.
Clients should discriminate on the presence of `url` (Checkout) vs `paymentIntentId` (auto-charged). Cards entered through the Checkout fallback are saved for future top-ups, so a customer's second top-up typically auto-charges.
# Send Email
Source: https://docs.recoupable.dev/api-reference/emails/create
api-reference/openapi/accounts.json POST /api/emails
Send an email to one or more recipients. Emails are sent from `Agent by Recoup `.
# Get Artist Fans
Source: https://docs.recoupable.dev/api-reference/fans/get
api-reference/openapi/releases.json GET /api/artists/{id}/fans
Retrieve all social profiles from fans of an artist across all platforms. This endpoint aggregates fan data from all connected social media platforms. Supports pagination for large fan lists.
# Generate Image
Source: https://docs.recoupable.dev/api-reference/image/generation
api-reference/openapi/content.json GET /api/image/generate
Generate high-quality images using AI models. Images are automatically stored on Arweave and include In Process moment metadata for provenance and ownership tracking.
# Add Artist to Organization
Source: https://docs.recoupable.dev/api-reference/organizations/add-artist
api-reference/openapi/accounts.json POST /api/organizations/artists
Add an artist to an organization. This allows organization members to access and manage the artist. This endpoint is idempotent - calling it multiple times with the same artistId and organizationId will not create duplicate records.
# Add Organization Domain
Source: https://docs.recoupable.dev/api-reference/organizations/add-domain
api-reference/openapi/accounts.json POST /api/organizations/domains
Map an email domain to an organization for automatic membership. After mapping, any account that signs up (or signs in) with an email at this domain is automatically added to the organization. A domain can belong to at most one organization. This endpoint is idempotent - re-adding the same domain to the same organization returns the existing mapping.
# Add Member to Organization
Source: https://docs.recoupable.dev/api-reference/organizations/add-member
api-reference/openapi/accounts.json POST /api/organizations/members
Add a member to an organization. This endpoint is idempotent - Adding an existing member returns the existing membership.
# Create Organization
Source: https://docs.recoupable.dev/api-reference/organizations/create
api-reference/openapi/accounts.json POST /api/organizations
Create a new organization. The creator is automatically added as a member of the organization.
# Get Organizations
Source: https://docs.recoupable.dev/api-reference/organizations/list
api-reference/openapi/accounts.json GET /api/organizations
Retrieve all organizations that the authenticated account belongs to. Pass account_id to retrieve organizations for a specific account the API key has access to.
# List Organization Domains
Source: https://docs.recoupable.dev/api-reference/organizations/list-domains
api-reference/openapi/accounts.json GET /api/organizations/domains
List the email domains mapped to an organization. Accounts that sign up with an email at a mapped domain automatically join the organization.
# Remove Organization Domain
Source: https://docs.recoupable.dev/api-reference/organizations/remove-domain
api-reference/openapi/accounts.json DELETE /api/organizations/domains
Remove an email domain mapping from an organization. New signups at this domain will no longer auto-join the organization; existing members are not affected. This endpoint is idempotent.
# Remove Member from Organization
Source: https://docs.recoupable.dev/api-reference/organizations/remove-member
api-reference/openapi/accounts.json DELETE /api/organizations/members
Remove a member from an organization. This endpoint is idempotent - Removing an account that is not a member succeeds without error.
# Get Artist Posts
Source: https://docs.recoupable.dev/api-reference/posts/get
api-reference/openapi/social.json GET /api/artists/{id}/posts
Retrieve all social media posts from an artist across all platforms. This endpoint aggregates posts from all connected social media profiles for the specified artist. Supports pagination for large post collections.
# List Pulses
Source: https://docs.recoupable.dev/api-reference/pulses/list
api-reference/openapi/accounts.json GET /api/pulses
Retrieve pulse information for the authenticated account. If the account has access to organizations, pass account_id to filter to a specific account within those organizations.
# Update Pulse
Source: https://docs.recoupable.dev/api-reference/pulses/update
api-reference/openapi/accounts.json PATCH /api/pulses
Update the pulse settings for an account. Use this to enable or disable the pulse. Returns an array of pulses for consistency with the GET endpoint.
# Album measurements
Source: https://docs.recoupable.dev/api-reference/research/album-measurements
api-reference/openapi/research.json GET /api/research/albums/{id}/measurements
Latest measured count per track on an album, from the measurement store. `{id}` is a Spotify album id.
# Albums
Source: https://docs.recoupable.dev/api-reference/research/albums
api-reference/openapi/research.json GET /api/research/albums
Get the album discography — albums, EPs, and singles with release dates — for a provider `artist_id`.
Fetches provider data for `/artist/:id/albums`. By default `is_primary=true`, so only albums where the artist is a main artist are returned — DJ compilations, soundtracks, and pure feature appearances are excluded. Pass `is_primary=false` to include them. Discover a provider `artist_id` via [GET /api/research](/api-reference/research/search) with `type=artists`.
# Audience Demographics
Source: https://docs.recoupable.dev/api-reference/research/audience
api-reference/openapi/research.json GET /api/research/audience
Get audience demographics for an artist on a specific platform — age, gender, and country breakdown.
# Career Timeline
Source: https://docs.recoupable.dev/api-reference/research/career
api-reference/openapi/research.json GET /api/research/career
Get an artist's career timeline — key milestones, trajectory, and career stage.
# Deep Research
Source: https://docs.recoupable.dev/api-reference/research/deep
api-reference/openapi/research.json POST /api/research/deep
Perform deep, comprehensive research on a topic. Browses multiple sources extensively and returns a cited report. Use for full artist deep dives, competitive analysis, and any research requiring synthesis across many sources.
# Enrich
Source: https://docs.recoupable.dev/api-reference/research/enrich
api-reference/openapi/research.json POST /api/research/enrich
Enrich an entity with structured data from web research. Provide a description of who or what to research and a JSON schema defining the fields to extract. Returns typed data with citations. **Important:** The `schema` object must include `"type": "object"` at the top level — requests without an explicit type will be rejected.
# Extract URL
Source: https://docs.recoupable.dev/api-reference/research/extract
api-reference/openapi/research.json POST /api/research/extract
Extract clean markdown content from one or more public URLs. Handles JavaScript-heavy pages and PDFs. Returns focused excerpts aligned to an objective, or full page content.
# AI Insights
Source: https://docs.recoupable.dev/api-reference/research/insights
api-reference/openapi/research.json GET /api/research/insights
Get AI-generated insights about an artist — automatically surfaced trends, milestones, and observations.
# Lookup by URL
Source: https://docs.recoupable.dev/api-reference/research/lookup
api-reference/openapi/research.json GET /api/research/lookup
Look up an artist by a platform URL or ID — Spotify URL, Spotify ID, Apple Music URL, etc.
# Create measurement job
Source: https://docs.recoupable.dev/api-reference/research/measurement-jobs
api-reference/openapi/research.json POST /api/research/measurement-jobs
One async ingest resource. `source:"current"` captures present counts via the snapshot pipeline. `source:"historical"` enqueues each resolved recording for Songstats deep backfill ranked by all-time streams (idempotent — songs already carrying `songstats` history are skipped; no track is fetched twice). Provide exactly one of `catalog_id` / `album_ids` / `isrcs` in `scope`. The returned `id` is a snapshot id you can pass to [Create catalog](/api-reference/songs/catalogs-create) to materialize the measured tracks into an account-owned catalog.
# Track measurements
Source: https://docs.recoupable.dev/api-reference/research/measurements
api-reference/openapi/research.json GET /api/research/tracks/{id}/measurements
Time-series of a track's measured counts.
# Platform Metrics
Source: https://docs.recoupable.dev/api-reference/research/metrics
api-reference/openapi/research.json GET /api/research/metrics
Get platform-specific metrics for an artist over time — followers, listeners, views, engagement, and radio airplay. Supports 16 sources.
# Milestones
Source: https://docs.recoupable.dev/api-reference/research/milestones
api-reference/openapi/research.json GET /api/research/milestones
Get an artist's activity feed — playlist adds, chart entries, and other notable events. Each milestone includes a date, summary, platform, track name, and star rating.
# People Search
Source: https://docs.recoupable.dev/api-reference/research/people
api-reference/openapi/research.json POST /api/research/people
Search for people in the music industry — artists, managers, A&R reps, producers. Returns multi-source profiles including LinkedIn data.
# Playlist Placements
Source: https://docs.recoupable.dev/api-reference/research/playlists
api-reference/openapi/research.json GET /api/research/playlists
Get an artist's playlist placements — editorial, algorithmic, and indie playlists across platforms.
# Artist Profile
Source: https://docs.recoupable.dev/api-reference/research/profile
api-reference/openapi/research.json GET /api/research/profile
Get a full artist profile — bio, genres, social URLs, label, career stage, and basic metrics.
# Search
Source: https://docs.recoupable.dev/api-reference/research/search
api-reference/openapi/research.json GET /api/research
Unified music research search. This is the discovery primitive for the detail-lookup endpoints — use `type=artists` to find an `id` for [GET /api/research/albums](/api-reference/research/albums), `type=tracks` for [GET /api/research/track](/api-reference/research/track), `type=playlists` for [GET /api/research/playlist](/api-reference/research/playlist), etc. Pick the right `id` from the returned results and pass it to the appropriate detail endpoint.
Searches the configured research data source. Use the `type` and `limit` parameters to narrow results before passing a returned `id` to a detail endpoint.
# Similar Artists
Source: https://docs.recoupable.dev/api-reference/research/similar
api-reference/openapi/research.json GET /api/research/similar
Find similar or related artists for competitive analysis and collaboration discovery. Weight parameters are applied when the configured research source supports weighted matching; otherwise the endpoint returns the closest available related-artist set.
# Track
Source: https://docs.recoupable.dev/api-reference/research/track
api-reference/openapi/research.json GET /api/research/track
Get full provider track metadata by track `id` — title, artists, albums, release date, genres, popularity, and platform IDs.
This endpoint is a thin proxy over the provider `/track/:id` detail lookup. Discover a provider track ID via [GET /api/research](/api-reference/research/search) with `type=tracks` — pick a result's `id`, then call this endpoint. Keeping the two concerns separate means predictable credit charging and no silent wrong-match behavior for ambiguous queries.
# Track Playlists
Source: https://docs.recoupable.dev/api-reference/research/track-playlists
api-reference/openapi/research.json GET /api/research/track/playlists
Returns playlists featuring a specific track. Accepts a provider track ID (`id`) or a track name + optional artist (`q`, `artist`) for a Spotify-powered lookup. When no filter flag is passed, defaults to editorial + indie + majorCurator + popularIndie = `true`. Costs 5 credits per request.
Discover a provider track `id` via [GET /api/research](/api-reference/research/search) with `type=tracks` — then pass the resulting `id` here for the most reliable match (avoids the ambiguity of name-based lookup).
# Track Stats
Source: https://docs.recoupable.dev/api-reference/research/track-stats
api-reference/openapi/research.json GET /api/research/track/stats
Get per-track, per-source current stats by ISRC or track id — absolute `streams_total`, playlist reach, and chart counts.
# Tracks
Source: https://docs.recoupable.dev/api-reference/research/tracks
api-reference/openapi/research.json GET /api/research/tracks
Get all tracks by an artist with popularity data.
# Social URLs
Source: https://docs.recoupable.dev/api-reference/research/urls
api-reference/openapi/research.json GET /api/research/urls
Get all social and streaming URLs for an artist — Spotify, Instagram, TikTok, YouTube, Twitter, SoundCloud, and more.
# Web Search
Source: https://docs.recoupable.dev/api-reference/research/web
api-reference/openapi/research.json POST /api/research/web
Search the web for real-time information. Returns ranked results with titles, URLs, and content snippets. Use for narrative context, press coverage, and cultural research that structured data endpoints don't cover.
# Create or restore session sandbox
Source: https://docs.recoupable.dev/api-reference/sandbox/create
POST /api/sandbox
Provisions a Sandbox for the given session. If a per-org base snapshot exists, the sandbox boots from it (skipping the full repo clone, ~75s saved). Otherwise the sandbox boots from the default base snapshot and a background workflow builds an org-specific snapshot for next time. When the session has prior runtime state (a paused or running sandbox under the same `sandboxName`), the call resumes it instead of creating a new one. On success, the session row is updated with the new `sandboxState` and lifecycle is bumped to `active`; the lifecycle workflow is kicked to manage hibernation and expiry from there.
# Reconnect to session sandbox
Source: https://docs.recoupable.dev/api-reference/sandbox/reconnect
GET /api/sandbox/reconnect
Live runtime probe for the sandbox bound to a session. Unlike `GET /api/sandbox/status` (DB-only read), this endpoint actually runs a quick command inside the sandbox to verify it is reachable. Used by the chat UI on session re-entry / tab refocus to decide whether to flip out of "loading sandbox…" or surface a "resume" affordance. Returns one of three operational outcomes via the `status` field: `"connected"` (sandbox is alive, included `expiresAt` reflects current expiry), `"expired"` (the runtime state is gone — the UI should offer to resume from snapshot if `hasSnapshot` is true, otherwise create a fresh sandbox), or `"no_sandbox"` (no sandbox has been provisioned for this session yet).
# Get session sandbox status
Source: https://docs.recoupable.dev/api-reference/sandbox/status
GET /api/sandbox/status
Returns the current lifecycle and runtime state for the sandbox bound to a session. The chat UI polls this endpoint while showing the "loading sandbox…" state and flips to "ready" when `status` becomes `active`. The response includes `lifecycleVersion` (an optimistic concurrency token) and a `lifecycle` envelope with `serverTime`, the lifecycle FSM `state`, and timestamps for last activity, hibernation deadline, and sandbox expiry. As a side effect, if the runtime state is stale (expired or overdue for hibernation), the lifecycle workflow is kicked to clean up — callers do not need to do this themselves.
# Create Sandbox
Source: https://docs.recoupable.dev/api-reference/sandboxes/create
api-reference/openapi/content.json POST /api/sandboxes
Create a new ephemeral sandbox environment. Optionally executes a command or an OpenCode prompt if provided. Sandboxes are isolated Linux microVMs that can be used to evaluate account-generated code, run AI agent output safely, or execute reproducible tasks. The sandbox will automatically stop after the timeout period. If no command or prompt is provided, the sandbox is created without triggering any background task. Use the prompt parameter as a shortcut to run `opencode run ""` in the sandbox. Pass account_id to create a sandbox for a specific account the API key has access to. Authentication is handled via the x-api-key header or Authorization Bearer token.
# Delete Sandbox
Source: https://docs.recoupable.dev/api-reference/sandboxes/delete
api-reference/openapi/content.json DELETE /api/sandboxes
Delete a sandbox environment for the authenticated account. This permanently deletes the associated GitHub repository and removes the account's snapshot record from the database. By default, deletes the sandbox for the key owner's account. Pass account_id to target a specific account the API key has access to. Authentication is handled via the x-api-key header or Authorization Bearer token.
# Get File Contents
Source: https://docs.recoupable.dev/api-reference/sandboxes/get-file
api-reference/openapi/content.json GET /api/sandboxes/file
Retrieve the contents of a file from the authenticated account's sandbox GitHub repository. Resolves the github_repo from the [account's snapshot](/api-reference/sandboxes/list), then fetches the file at the specified path from the repository's main branch. **Text files are returned verbatim. Binary files (`.mp3`, `.png`, `.jpg`, `.mp4`, `.pdf`, etc.) are returned base64-encoded — decode before writing to disk.** Authentication is handled via the x-api-key header or Authorization Bearer token.
# List Sandboxes
Source: https://docs.recoupable.dev/api-reference/sandboxes/list
api-reference/openapi/content.json GET /api/sandboxes
List all sandboxes associated with the authenticated account and their current statuses. Returns sandbox details including lifecycle state, timeout remaining, and creation timestamp. Pass account_id to retrieve sandboxes for a specific account the API key has access to. Authentication is handled via the x-api-key header or Authorization Bearer token.
# Setup Sandbox
Source: https://docs.recoupable.dev/api-reference/sandboxes/setup
api-reference/openapi/content.json POST /api/sandboxes/setup
Triggers the setup-sandbox background task to create a personal sandbox, provision a GitHub repo, take a snapshot, and shut down. By default, sets up the sandbox for the key owner's account. Pass account_id to target a specific account the API key has access to. Authentication is handled via the x-api-key header or Authorization Bearer token.
# Update Snapshot
Source: https://docs.recoupable.dev/api-reference/sandboxes/snapshot
api-reference/openapi/content.json PATCH /api/sandboxes
Set a custom snapshot ID for an account. By default, updates the key owner's account. Pass account_id to target a specific account the API key has access to. This allows accounts to use a specific sandbox snapshot when creating new sandboxes, enabling reproducible environments with pre-configured tools, dependencies, and files.
# Stage File
Source: https://docs.recoupable.dev/api-reference/sandboxes/stage-file
api-reference/openapi/content.json POST /api/sandboxes/staged-file
Issue a presigned upload token so the browser can upload a file directly to Vercel Blob, then call `POST /api/sandboxes/files` with the resulting blob URL to commit it to the sandbox repo. Use `upload()` from `@vercel/blob/client` rather than calling this route by hand. Max file size 100MB.
# Upload Files
Source: https://docs.recoupable.dev/api-reference/sandboxes/upload-files
api-reference/openapi/content.json POST /api/sandboxes/files
Upload one or more files to the authenticated account's sandbox GitHub repository. Accepts an array of file URLs and commits each file to the specified directory path within the repository. Supports submodule resolution — if the target path falls within a git submodule, the file is committed to the submodule's repository. Authentication is handled via the x-api-key header or Authorization Bearer token.
# Create Session
Source: https://docs.recoupable.dev/api-reference/sessions/create
api-reference/openapi/sessions.json POST /api/sessions
Creates a new agent session and an initial empty chat in a single transaction. The session is created in the `provisioning` lifecycle state — a separate orchestration step claims it and starts the sandbox.
# Create Session Chat
Source: https://docs.recoupable.dev/api-reference/sessions/create-chat
api-reference/openapi/sessions.json POST /api/sessions/{sessionId}/chats
Creates a new chat inside the given session. Callers may pass `{ id }` to claim a deterministic chat id — useful for optimistic UI flows where the client generates the id locally and then persists it. If a chat with that id already exists in **this** session the call is idempotent and returns the existing row; if it exists in **another** session, 409 is returned.
# Delete Session Chat
Source: https://docs.recoupable.dev/api-reference/sessions/delete-chat
api-reference/openapi/sessions.json DELETE /api/sessions/{sessionId}/chats/{chatId}
Removes the chat (cascade clears `chat_messages` and `chat_reads`). Refuses with 400 if this is the only chat in the session — sessions must always retain at least one chat.
# Get Session
Source: https://docs.recoupable.dev/api-reference/sessions/get
api-reference/openapi/sessions.json GET /api/sessions/{sessionId}
Returns a single agent session by its id.
# Get Session Chat
Source: https://docs.recoupable.dev/api-reference/sessions/get-chat
api-reference/openapi/sessions.json GET /api/sessions/{sessionId}/chats/{chatId}
Returns the chat's persisted UI message stream plus its current streaming state so callers can hydrate or refresh a chat view. `messages` is an array of `parts` payloads — one per `chat_messages` row — ordered by `created_at` ascending (ties broken by id). `isStreaming` is derived from `activeStreamId`.
# List Session Chats
Source: https://docs.recoupable.dev/api-reference/sessions/list-chats
api-reference/openapi/sessions.json GET /api/sessions/{sessionId}/chats
Lists every chat in the given session as a `ChatSummary` (chat row plus per-account `hasUnread` and `isStreaming` flags), along with the caller's default model id. Chats are sorted by `createdAt` ascending.
# Mark Chat Read
Source: https://docs.recoupable.dev/api-reference/sessions/mark-chat-read
api-reference/openapi/sessions.json POST /api/sessions/{sessionId}/chats/{chatId}/read
Marks a session chat as read for the authenticated account.
# Update Session
Source: https://docs.recoupable.dev/api-reference/sessions/patch
api-reference/openapi/sessions.json PATCH /api/sessions/{sessionId}
Rename a session, change lifecycle status, or update line counters.
# Update Session Chat
Source: https://docs.recoupable.dev/api-reference/sessions/patch-chat
api-reference/openapi/sessions.json PATCH /api/sessions/{sessionId}/chats/{chatId}
Applies a partial update to the chat. Body must include at least one of `title` or `modelId` and any provided value must be a non-empty string (whitespace is trimmed for `title`).
# Social Scrape
Source: https://docs.recoupable.dev/api-reference/social/scrape
api-reference/openapi/social.json POST /api/socials/{id}/scrape
Trigger a social profile scraping job for a given social profile. Use the [Get Artist Socials](/api-reference/artists/socials) endpoint first to retrieve the social profile id values. The response returns run metadata for polling status and retrieving results via the [Scraper Results API](/api-reference/apify/scraper).
# Analyze Songs
Source: https://docs.recoupable.dev/api-reference/songs/analyze
api-reference/openapi/releases.json POST /api/songs/analyze
Analyze music using a state-of-the-art Audio Language Model that listens directly to the audio waveform. Unlike text-based AI, this model processes the actual sound — identifying harmony, structure, timbre, lyrics, and cultural context through deep music understanding. Supports audio up to 20 minutes (MP3, WAV, FLAC). Two modes: (1) **Presets** — pass a `preset` name like `catalog_metadata`, `mood_tags`, or `full_report` for structured, optimized output. (2) **Custom prompt** — pass a `prompt` for free-form questions. The `full_report` preset runs all 13 presets in parallel and returns a comprehensive music intelligence report. Use `GET /api/songs/analyze/presets` to list available presets.
# List Analyze Presets
Source: https://docs.recoupable.dev/api-reference/songs/analyze-presets
api-reference/openapi/releases.json GET /api/songs/analyze/presets
Lists all available music analysis presets. Each preset is a curated prompt with optimized generation parameters for a specific use case (e.g. catalog metadata enrichment, sync licensing analysis, audience profiling). Requires authentication via API key or Bearer token.
# Get Catalog Measurements
Source: https://docs.recoupable.dev/api-reference/songs/catalog-measurements
get /api/catalogs/{catalogId}/measurements
Get the latest play counts and a derived valuation band for a catalog. Measurements are captured by [Create measurement job](/api-reference/research/measurement-jobs) runs; the band is computed at read time from the latest capture per song.
# Get Catalog Songs
Source: https://docs.recoupable.dev/api-reference/songs/catalog-songs
get /api/catalogs/songs
Retrieve songs within a specific catalog with pagination support. This endpoint joins catalog_songs with songs, song_artists, and accounts to provide comprehensive song information for a given catalog.
This endpoint supports pagination. The Catalog Songs API also supports POST for adding songs and DELETE for removing songs. See the [Add Catalog Songs](/api-reference/songs/catalog-songs-add) and [Remove Catalog Songs](/api-reference/songs/catalog-songs-delete) endpoints.
# Add Catalog Songs
Source: https://docs.recoupable.dev/api-reference/songs/catalog-songs-add
post /api/catalogs/songs
Batch add songs to a catalog by ISRC. For each song, the API attempts to look up metadata via internal search. If no data is found, optional fallback fields (name, album, notes, artists) are used.
For each song, the API attempts to look up metadata via internal search. If no data is found, optional fallback fields (name, album, notes, artists) are used.
# Remove Catalog Songs
Source: https://docs.recoupable.dev/api-reference/songs/catalog-songs-delete
delete /api/catalogs/songs
Batch remove songs from a catalog by ISRC. Deletes the relationship in catalog_songs for each catalog_id and ISRC pair.
This endpoint removes the relationship in `catalog_songs` for each `catalog_id` and ISRC pair. The song data itself is not deleted.
# Get Catalogs
Source: https://docs.recoupable.dev/api-reference/songs/catalogs
api-reference/openapi/releases.json GET /api/accounts/{id}/catalogs
Retrieve catalogs associated with a specific account. The endpoint joins account_catalogs with catalogs to return catalog metadata for the specified account.
# Create Catalog
Source: https://docs.recoupable.dev/api-reference/songs/catalogs-create
post /api/catalogs
Create a catalog. When materializing from a valuation snapshot, the endpoint also attaches the snapshot's canonical artist to the caller's roster: the measured songs' existing song-artist links are resolved to the dominant artist account, which is added to the caller's roster if not already present. The attach also runs on idempotent re-claims of an already-materialized snapshot.
# Create Songs
Source: https://docs.recoupable.dev/api-reference/songs/create
post /api/songs
Bulk create or fetch songs by ISRC. For each song, the API attempts to look up metadata via internal search. If no data is found, optional fallback fields (name, album, notes, artists) are used.
This endpoint performs bulk create/fetch operations. For each song, the API attempts to look up metadata via internal search. If no data is found, optional fallback fields (name, album, notes, artists) are used.
# Get Songs
Source: https://docs.recoupable.dev/api-reference/songs/songs
get /api/songs
Retrieve songs from the database with optional filtering by ISRC (International Standard Recording Code) or artist account. This endpoint joins the songs table with song_artists and accounts tables to provide comprehensive song information.
The Songs API also supports POST requests for bulk create/fetch operations. See the [Create Songs](/api-reference/songs/create) endpoint.
# Get Album
Source: https://docs.recoupable.dev/api-reference/spotify/album
api-reference/openapi/social.json GET /api/spotify/album
Get Spotify catalog information for a single album.
# Get Artist
Source: https://docs.recoupable.dev/api-reference/spotify/artist
api-reference/openapi/social.json GET /api/spotify/artist/
Get Spotify catalog information for a single artist identified by their unique Spotify ID.
# Get Artist Albums
Source: https://docs.recoupable.dev/api-reference/spotify/artist-albums
api-reference/openapi/social.json GET /api/spotify/artist/albums
Get Spotify catalog information about an artist's albums.
# Get Artist Top Tracks
Source: https://docs.recoupable.dev/api-reference/spotify/artist-top-tracks
api-reference/openapi/social.json GET /api/spotify/artist/topTracks
Get an artist's top tracks by country.
# Search
Source: https://docs.recoupable.dev/api-reference/spotify/search
api-reference/openapi/social.json GET /api/spotify/search
Search for artists, albums, tracks, and playlists using the Spotify API. This endpoint is a proxy to the official Spotify Search API.
# Create Subscription Portal
Source: https://docs.recoupable.dev/api-reference/subscriptions/portal-create
api-reference/openapi/accounts.json POST /api/subscriptions/portal
Create a subscription management session for the authenticated account. Returns a hosted URL where the customer can update payment method, view invoices, or cancel. The client should redirect the user to that URL.
# Create Subscription Session
Source: https://docs.recoupable.dev/api-reference/subscriptions/sessions-create
api-reference/openapi/accounts.json POST /api/subscriptions/sessions
Create a checkout session to start a subscription for the authenticated account. Returns a hosted checkout URL that the client should redirect to. The session is pre-configured with a 30-day trial period.
# Create Task
Source: https://docs.recoupable.dev/api-reference/tasks/create
api-reference/openapi/releases.json POST /api/tasks
Create a new scheduled task that runs a prompt against an artist on a recurring cron schedule. The response matches the [GET endpoint](/api-reference/tasks/get) (a `TasksResponse` with the created task in the `tasks` array).
# Delete Task
Source: https://docs.recoupable.dev/api-reference/tasks/delete
api-reference/openapi/releases.json DELETE /api/tasks
Delete an existing scheduled task by `id`. Returns only the delete operation status.
# Get Tasks
Source: https://docs.recoupable.dev/api-reference/tasks/get
api-reference/openapi/releases.json GET /api/tasks
Retrieve scheduled tasks. Each task includes `recent_runs` (last 5 runs), `upcoming` (next scheduled run times) sourced directly from the Trigger.dev API, and `owner_email` when an account email exists for the task owner. Supports filtering by id, account_id, or artist_account_id.
# Get Task Runs
Source: https://docs.recoupable.dev/api-reference/tasks/runs
api-reference/openapi/releases.json GET /api/tasks/runs
Returns task runs for the authenticated account. When `runId` is provided, the response contains that single run (`runs` length 1) or 404 if not found. When `runId` is omitted, returns recent runs filtered by account context (default authenticated account, or `account_id` override when authorized).
# Update Task
Source: https://docs.recoupable.dev/api-reference/tasks/update
api-reference/openapi/releases.json PATCH /api/tasks
Update an existing scheduled task. Only the id field is required; any additional fields you include will be updated on the task. The response shape matches the GET endpoint (an array containing the updated task).
# Create Template
Source: https://docs.recoupable.dev/api-reference/templates/create
api-reference/openapi/templates.json POST /api/agents/templates
Create a new template owned by the authenticated account. When `is_private` is true, the optional `share_emails` array grants explicit read access to the listed accounts; for public templates the field is ignored.
# Delete Template
Source: https://docs.recoupable.dev/api-reference/templates/delete
api-reference/openapi/templates.json DELETE /api/agents/templates/{id}
Permanently delete an template. Only the owner of the template may perform this action. Associated share records and favorite entries are removed as part of the deletion.
# Favorite Template
Source: https://docs.recoupable.dev/api-reference/templates/favorite
api-reference/openapi/templates.json PUT /api/agents/templates/{id}/favorite
Mark or unmark an template as a favorite for the authenticated account. The endpoint is idempotent - calling it repeatedly with the same `is_favourite` value has no additional effect. The caller must be able to see the template (own it, the template is public, or it has been shared with them).
# List Templates
Source: https://docs.recoupable.dev/api-reference/templates/list
api-reference/openapi/templates.json GET /api/agents/templates
Retrieve every template visible to the authenticated account. The response combines templates the account owns, public templates created by other accounts, and private templates that have been shared with the authenticated account's email.
# Update Template
Source: https://docs.recoupable.dev/api-reference/templates/update
api-reference/openapi/templates.json PATCH /api/agents/templates/{id}
Update fields on an existing template owned by the authenticated account. All body fields are optional and only the supplied fields are modified. Providing `share_emails` replaces the existing share list for the template.
# Transcribe Audio
Source: https://docs.recoupable.dev/api-reference/transcribe/audio
api-reference/openapi/content.json POST /api/transcribe
Transcribe audio files using OpenAI Whisper. The API saves both the original audio file and the generated markdown transcript to the customer's files in Supabase Storage.
# Create Workspace
Source: https://docs.recoupable.dev/api-reference/workspaces/create
api-reference/openapi/accounts.json POST /api/workspaces
Create a new workspace account. Workspaces can optionally be linked to an organization.
# Authentication
Source: https://docs.recoupable.dev/authentication
How authentication works in the Recoup API — API keys, access tokens, and organization access control.
## Overview
Every request to the Recoup API must be authenticated using exactly one of two mechanisms:
| Method | Header | Use case |
| ------------ | ------------------------------- | ------------------------------------- |
| API Key | `x-api-key` | Server-to-server integrations |
| Access Token | `Authorization: Bearer ` | Frontend apps authenticated via Privy |
Providing both headers in the same request will result in a `401` error.
Agent onboarding endpoints (`POST /api/agents/signup` and `POST /api/agents/verify`) are **unauthenticated** — they exist so agents can obtain their first API key. See the [Agents guide](/agents) for details.
***
## API Keys
API keys are the primary way to authenticate programmatic access to the Recoup API. All API keys are **personal keys** — they are always tied to the account that created them.
### Creating an API Key
1. Navigate to [chat.recoupable.dev/keys](https://chat.recoupable.dev/keys)
2. Enter a descriptive name (e.g. `"Production Server"`)
3. Click **Create API Key**
Copy your API key immediately — it is only shown once. Keys are stored as a secure HMAC-SHA256 hash and cannot be retrieved after creation.
### Using an API Key
Pass your key in the `x-api-key` header:
```bash theme={null}
curl -X GET "https://api.recoupable.dev/api/tasks" \
-H "x-api-key: YOUR_API_KEY"
```
### Access to Organizations
If your account belongs to one or more organizations, your API key can access data across those organizations by passing an `account_id` parameter on supported endpoints. This lets you filter to any account within an organization your key has access to.
* **No org membership** — the key can only access its own account's data
* **Org member** — the key can pass `account_id` to filter to any account within that organization
Org membership is determined by the account's [organizations](/api-reference/organizations/list). An account gains access to an org when it is added as a member.
***
## Access Tokens (Privy)
If you're building a frontend application that authenticates users via [Privy](https://privy.io), you can pass the user's Privy JWT as a Bearer token instead of an API key.
```bash theme={null}
curl -X GET "https://api.recoupable.dev/api/tasks" \
-H "Authorization: Bearer YOUR_PRIVY_JWT"
```
The API validates the token against Privy, extracts the user's email, and resolves it to the corresponding Recoup account. Bearer tokens always authenticate as a personal account — they cannot act on behalf of an organization.
***
## How We Verify Access on API Calls
Every authenticated request goes through `validateAuthContext`, which enforces the following access rules:
### API Key or Bearer Token
By default, requests access the key owner's own account. When `account_id` is provided:
```
Request includes account_id override?
├── Same as key owner → Allowed (self-access)
├── Key owner is a member of an org that contains account_id → Allowed
└── No matching org membership → 403 Forbidden
```
Membership is verified by checking the key owner's [organizations](/api-reference/organizations/list) for a record linking the account to the target account's organization.
The Recoup internal admin organization has universal access to all accounts.
### Organization Access via `organization_id`
Some endpoints accept an `organization_id` parameter. When provided, the API additionally validates that the authenticated account is either:
* A **member** of the organization, or
* The **organization account itself**
***
## Error Responses
| Status | Cause |
| ------ | -------------------------------------------------------------------------------------------- |
| `401` | Missing or invalid credentials, or both `x-api-key` and `Authorization` headers provided |
| `403` | Valid credentials but insufficient access to the requested `account_id` or `organization_id` |
***
## Security Notes
* API keys are **never stored in plaintext** — only an HMAC-SHA256 hash (keyed with your project secret) is persisted in the database
* **Never include `account_id` in your API key creation request** — the account is always derived from your authenticated credentials
* Rotate keys immediately if compromised via the [API Keys Management Page](https://chat.recoupable.dev/keys)
# CLI
Source: https://docs.recoupable.dev/cli
Install the Recoup CLI and interact with the platform from your terminal.
The Recoup CLI (`@recoupable/cli`) wraps the Recoup API for terminal-first workflows. It's available as a global npm package and comes pre-installed in sandbox environments.
**The CLI is in beta.** The commands listed below are what's shipped today (v0.1.13). For research workflows and most content operations, call the [REST API](/api-reference) directly — the CLI is gradually catching up.
**Agents:** if a command isn't listed below, don't retry — fall back to the corresponding REST endpoint linked under each command.
## Install
```bash theme={null}
npm install -g @recoupable/cli
```
## Authenticate
Set your API key as an environment variable:
```bash theme={null}
export RECOUP_API_KEY=your-api-key
```
Verify it works:
```bash theme={null}
recoup whoami
```
Get an API key from the [API Keys page](https://chat.recoupable.dev/keys) or use the [agent signup](/agents) for instant key generation.
## Configuration
| Variable | Required | Default | Description |
| ---------------- | -------- | ---------------------------- | --------------------- |
| `RECOUP_API_KEY` | Yes | — | Your Recoup API key |
| `RECOUP_API_URL` | No | `https://api.recoupable.dev` | API base URL override |
All commands support `--json` for machine-readable output and `--help` for usage info.
***
## Commands
### whoami
Show the authenticated account. See [`GET /api/accounts/id`](/api-reference/accounts/id).
```bash theme={null}
recoup whoami
recoup whoami --json
```
### orgs
List organizations. See [`GET /api/organizations`](/api-reference/organizations/list).
```bash theme={null}
recoup orgs list
recoup orgs list --account
```
### artists
List artists. See [`GET /api/artists`](/api-reference/artists/list).
```bash theme={null}
recoup artists list
recoup artists list --org
recoup artists list --account
```
### emails
Send an email to the authenticated account. See [`POST /api/emails`](/api-reference/emails/create).
```bash theme={null}
recoup emails --subject "Pulse Report" --text "Here's your weekly summary."
recoup emails --subject "Update" --html "Report
Details here.
"
```
| Flag | Required | Description |
| ----------------------- | -------- | ---------------------------------------------- |
| `--subject ` | Yes | Email subject line |
| `--text ` | No | Plain text or Markdown body |
| `--html ` | No | Raw HTML body (takes precedence over `--text`) |
| `--cc ` | No | CC recipient (repeatable) |
| `--room-id ` | No | Room ID for a chat link in the email footer |
| `--account ` | No | Send to a specific account (org keys only) |
### chats
Manage chats. See [`GET /api/chats`](/api-reference/chat/chats) and [`POST /api/chats`](/api-reference/chat/create).
```bash theme={null}
recoup chats list
recoup chats create --name "My Topic"
recoup chats create --name "My Topic" --artist
```
### sandboxes
Manage sandboxes. See [`GET /api/sandboxes`](/api-reference/sandboxes/list) and [`POST /api/sandboxes`](/api-reference/sandboxes/create).
```bash theme={null}
recoup sandboxes list
recoup sandboxes create
recoup sandboxes create --command "ls -la"
```
### tasks
Check background task status. See [`GET /api/tasks/runs`](/api-reference/tasks/runs).
```bash theme={null}
recoup tasks status --run
```
### songs
Run AI music analysis. See [`POST /api/songs/analyze`](/api-reference/songs/analyze) and [`GET /api/songs/analyze/presets`](/api-reference/songs/analyze-presets).
```bash theme={null}
recoup songs presets
recoup songs analyze --preset catalog_metadata --audio https://example.com/track.mp3
recoup songs analyze --prompt "Describe the production style" --audio https://example.com/track.mp3
```
One of `--preset` or `--prompt` is required. The other flags are optional.
| Flag | Required | Description |
| ------------------ | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `--preset ` | Conditional | Curated analysis preset. Required when `--prompt` is omitted. |
| `--prompt ` | Conditional | Custom text prompt. Required when `--preset` is omitted. |
| `--audio ` | No | Public URL to the audio file (MP3, WAV, FLAC). Some presets analyze the audio file; others (like `catalog_metadata`) work from metadata alone. |
| `--max-tokens ` | No | Max tokens to generate (default 512). |
***
## content
Content creation pipeline — generate AI-powered social videos for artists.
### List templates
```bash theme={null}
recoup content templates
```
### Validate an artist
Check that an artist has the required assets before creating content. See [`GET /api/content/validate`](/api-reference/content/validate).
```bash theme={null}
recoup content validate --artist
```
### Estimate cost
Preview estimated cost and duration before kicking off the pipeline. See [`POST /api/content/estimate`](/api-reference/content/estimate).
```bash theme={null}
recoup content estimate --artist
recoup content estimate --artist --template
```
### Create content
Run the full content-creation pipeline for an artist. See [`POST /api/content/create`](/api-reference/content/create).
```bash theme={null}
recoup content create --artist
recoup content create --artist --template --lipsync --upscale
```
| Flag | Required | Description |
| ---------------------- | -------- | -------------------------------- |
| `--artist ` | Yes | Artist account ID |
| `--template ` | No | Template name (default: random) |
| `--lipsync` | No | Enable lipsync mode |
| `--upscale` | No | Enable upscaling |
| `--caption-length ` | No | Max caption length in characters |
For finer-grained control (individual image, video, caption, transcription, edit, upscale, or analyze operations), call the [content REST endpoints](/api-reference/content/generate-image) directly. Those primitives aren't yet exposed as individual CLI subcommands.
# Connection Ownership
Source: https://docs.recoupable.dev/connectors/ownership
The connector connection-ownership and authority contract: who owns a connection, who can act through it, and why roster membership never grants execute rights.
## Overview
Connectors link third-party services (Google Sheets, TikTok, YouTube, X, LinkedIn, and others) to Recoup so agents can act on an artist's behalf. This page defines the **ownership and authority contract** for those connections: who a connection belongs to, and who is allowed to authorize, execute through, or disconnect it.
This contract is the source of truth for connector access control. Endpoint request and response shapes are documented separately in the [Connectors API reference](/api-reference/connectors/list).
***
## Association ≠ Authority
Artists in Recoup are **canonical and shared**. The same artist can appear in many accounts' rosters and in multiple organizations. Being associated with an artist is not the same as having authority to act through that artist's connections:
* An artist appearing in an account's roster (`account_artist_ids`) grants **read and analytics access only**.
* An artist appearing in an organization's roster likewise grants **read and analytics access only** to org members.
* Neither form of association ever grants the right to authorize, execute, or disconnect a connection.
Roster membership never inherits connection authority. If Account A connects an artist's TikTok, Account B having that same artist on its roster does **not** let Account B post through that connection.
***
## Connection Scope
Connections are scoped to the **relationship between an owner and an artist**, not to the bare canonical artist:
| Connection type | Scoped to |
| --------------- | --------------------------------- |
| Personal | The `(account, artist)` pair |
| Org-shared | The `(organization, artist)` pair |
The connection is keyed on the **join row** (the specific account-to-artist or org-to-artist relationship), never on the canonical artist alone. Two accounts that both roster the same artist hold two independent connection scopes for that artist.
**Whoever establishes a connection owns it.** Ownership is set at authorization time and does not transfer through roster changes.
Because artists stay canonical and shared, **isolation lives on the connection**: sharing an artist across accounts and orgs is safe precisely because each connection is confined to the relationship that created it.
***
## Authority Matrix
| Capability | Who has it |
| ------------------------------------ | ----------------------------------------------------------------------------------------- |
| Read / analytics on an artist | Any account or org member with the artist in their roster |
| Authorize a new connection | The account (or org member, for org-shared) establishing the connection, who then owns it |
| Execute actions through a connection | The owning account only; for org-shared connections, members of the owning org |
| Disconnect a connection | The owning account only; for org-shared connections, members of the owning org |
| Admin override | Recoup staff only (admins of the Recoup internal organization) |
The admin override exists for support and abuse response. No customer account or organization, regardless of roster or org membership, can override another owner's connection.
***
## Relationship to the Current API Reference
The [Connectors endpoint reference](/api-reference/connectors/list) currently describes connections as scoped to the authenticated account alone. That reflects behavior that shipped before this contract; the API is being re-keyed to the per-`(account, artist)` / per-`(organization, artist)` model defined here. Where the two disagree, **this page is the authority contract**. Endpoint docs will be updated as the re-keyed API ships.
Endpoint request and response shapes for the re-keyed model are deliberately not documented here yet.
# Content
Source: https://docs.recoupable.dev/content-agent
Generate images, videos, captions, and social-ready content using AI-powered primitives
## Overview
Recoup's content API gives you seven independent primitives for generating and editing visual content. Each primitive does one thing well. You orchestrate them.
**Every primitive works without a template.** Pass your own prompt, reference images, and parameters directly. Templates are optional shortcuts — opinionated creative recipes that pre-fill parameters for a specific look.
## Primitives
| Primitive | Endpoint | What it does |
| ---------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| Generate Image | [POST /api/content/image](/api-reference/content/generate-image) | Create an image from a text prompt, optionally with a reference image for face/style |
| Generate Video | [POST /api/content/video](/api-reference/content/generate-video) | Create a video — 6 modes: prompt, animate, reference, extend, first-last, lipsync |
| Generate Caption | [POST /api/content/caption](/api-reference/content/generate-caption) | Generate on-screen text for social media videos |
| Transcribe Audio | [POST /api/content/transcribe](/api-reference/content/transcribe-audio) | Transcribe audio to timestamped lyrics/text |
| Edit Content | [PATCH /api/content](/api-reference/content/edit) | Trim, crop, resize, overlay text, or add audio — one processing pass |
| Upscale | [POST /api/content/upscale](/api-reference/content/upscale) | Upscale image or video resolution (up to 4x) |
| Analyze Video | [POST /api/content/analyze](/api-reference/content/analyze-video) | AI video analysis — describe scenes, check quality, evaluate content |
There is also [POST /api/content/create](/api-reference/content/create) which runs the full pipeline in one call — use it when you want a video without creative control over each step.
## How It Works
### Without a template (malleable mode)
Pass your own parameters directly to any primitive. Maximum creative control.
```bash theme={null}
# Generate an image with your own prompt
curl -X POST https://api.recoupable.dev/api/content/image \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt": "A moody portrait in a dimly lit room, front-facing phone camera"}'
# Generate a video from that image
curl -X POST https://api.recoupable.dev/api/content/video \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"image_url": "IMAGE_URL_FROM_ABOVE", "prompt": "subtle breathing motion, nearly still"}'
```
### With a template (shortcut mode)
Pass a template ID and the primitive fills in prompts, reference images, and style rules automatically. You can still override any parameter.
```bash theme={null}
# Same image, but the template provides the prompt and reference images
curl -X POST https://api.recoupable.dev/api/content/image \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"template": "artist-caption-bedroom", "reference_image_url": "YOUR_FACE_IMAGE"}'
```
Use [GET /api/content/templates](/api-reference/content/templates) to see available templates with descriptions.
## Templates
A template is a complete creative recipe — it defines what a piece of content looks like across every primitive:
* **Image config**: prompt, reference images, style rules (camera, lighting, composition)
* **Video config**: mood variations, movement descriptions
* **Caption config**: tone, formatting rules, example captions
* **Edit config**: crop ratio, text overlay style, audio mixing
Templates are optional. They save time by pre-filling parameters with curated defaults. When you see customers repeatedly creating the same kind of content, that pattern becomes a template.
### Override priority
When using a template, your explicit parameters always win:
1. **Your params** — highest priority. What you pass overrides everything.
2. **Artist context** — if the artist has a style guide, it personalizes the template.
3. **Template defaults** — lowest priority. The recipe's built-in values.
## Video Modes
The video primitive supports 6 generation modes:
| Mode | What it does | Required inputs |
| ------------ | ---------------------------------------------- | -------------------------------------- |
| `prompt` | Create from text description | `prompt` |
| `animate` | Animate a still image | `image_url`, `prompt` |
| `reference` | Use image as style reference (not first frame) | `image_url`, `prompt` |
| `extend` | Continue an existing video | `video_url`, `prompt` |
| `first-last` | Transition between two images | `image_url`, `end_image_url`, `prompt` |
| `lipsync` | Sync face to audio | `image_url`, `audio_url` |
Set `mode` explicitly, or omit it and the API infers the mode from the inputs you provide.
## Iteration
Each primitive is independent. Redo any step without rerunning the whole pipeline:
* Bad image? Regenerate with a different prompt or reference
* Caption too long? Regenerate with `length: "short"`
* Video glitchy? Analyze it, then regenerate with adjusted params
* Clip too short? Use `extend` mode to continue it
* Low quality? Upscale the image or video
* Everything good but wrong caption? Just re-run the edit step
## Content Agent (Slack Bot)
The **Recoup Content Agent** is a Slack bot that generates social-ready artist videos on @mention. It plugs into the content creation pipeline and delivers results directly in your Slack thread.
### @Mention Syntax
```
@RecoupContentAgent [template] [batch=N] [lipsync]
```
| Parameter | Required | Description |
| ------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `artist_account_id` | Yes | UUID of the artist account |
| `template` | No | Content template name. Optional — when omitted, the pipeline runs with default settings. See [GET /api/content/templates](/api-reference/content/templates) for options. |
| `batch=N` | No | Number of videos to generate (1-30, default 1) |
| `lipsync` | No | Enable lipsync mode (audio baked into video) |
### Examples
**Basic — single video with default template:**
```
@RecoupContentAgent abc-123-uuid
```
**Custom template:**
```
@RecoupContentAgent abc-123-uuid artist-caption-bedroom
```
**Batch with lipsync:**
```
@RecoupContentAgent abc-123-uuid batch=3 lipsync
```
### Architecture
| Component | Location | Purpose |
| ----------------- | ---------------------------------- | ------------------------------------------------- |
| Slack webhook | `POST /api/content-agent/slack` | Receives @mention events |
| Callback endpoint | `POST /api/content-agent/callback` | Receives polling results |
| Bot singleton | `lib/content-agent/bot.ts` | Chat SDK with Slack adapter + Redis state |
| Mention handler | `lib/content-agent/handlers/` | Parses args, validates artist, triggers pipeline |
| Poll task | `poll-content-run` (Trigger.dev) | Monitors content runs, posts results via callback |
### Data Flow
1. **Slack event** → `POST /api/content-agent/slack` handles the webhook
2. **Mention handler** parses the command, calls [`GET /api/content/validate`](/api-reference/content/validate) to check artist readiness
3. **Content creation** triggered via [`POST /api/content/create`](/api-reference/content/create) — returns `runIds`
4. **Poll task** (`poll-content-run`) monitors the Trigger.dev runs every 30 seconds (up to 30 minutes)
5. **Callback** → [`POST /api/content-agent/callback`](/api-reference/content-agent/callback) receives results and posts video URLs back to the Slack thread
### Setup
#### 1. Create a Slack App
1. Go to [api.slack.com/apps](https://api.slack.com/apps) and create a new app
2. Under **OAuth & Permissions**, add bot scopes:
* `chat:write` — post messages
* `app_mentions:read` — receive @mention events
3. Under **Event Subscriptions**:
* Enable events
* Set the request URL to `https://api.recoupable.dev/api/content-agent/slack`
* Subscribe to `app_mention` bot event
4. Install the app to your workspace
#### 2. Configure Environment Variables
| Variable | Where | Description |
| ------------------------------- | ------------------- | -------------------------------------------------------------------- |
| `SLACK_CONTENT_BOT_TOKEN` | API (Vercel) | Bot OAuth token (`xoxb-...`) from Slack app |
| `SLACK_CONTENT_SIGNING_SECRET` | API (Vercel) | Signing secret from Slack app **Basic Information** |
| `CONTENT_AGENT_CALLBACK_SECRET` | API + Tasks | Shared secret for callback authentication (generate a random string) |
| `RECOUP_API_KEY` | API + Tasks | Recoup API key for authenticating pipeline requests |
| `RECOUP_API_BASE_URL` | Tasks (Trigger.dev) | API base URL (e.g., `https://api.recoupable.dev`) |
#### 3. Verify
Mention the bot in any Slack channel where it's been added:
```
@RecoupContentAgent
```
You should see:
1. An immediate acknowledgment message
2. A video URL reply in the thread after \~5-10 minutes
### Troubleshooting
| Issue | Cause | Fix |
| ---------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------ |
| No response from bot | Event subscription URL not configured | Check Slack app Event Subscriptions |
| "Artist not found" | Invalid `artist_account_id` | Verify the UUID exists in the platform |
| "No GitHub repository found" | Artist missing repo config | Ensure the artist account has a linked GitHub repo |
| Timeout after 30 min | Pipeline took too long | Check Trigger.dev dashboard for the failed run |
| "Unsupported template" | Invalid template name | Use [`GET /api/content/templates`](/api-reference/content/templates) to list available templates |
# Credits
Source: https://docs.recoupable.dev/credits
How Recoup credits work — what's billed, how to check your balance, and how to upgrade.
Some Recoup endpoints are billed in **credits** — primarily endpoints that hit external data providers, run AI inference, or generate content. The rest of the API is free at the API layer.
***
## What's billed
| Family | Billed? | Notes |
| ---------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Research** ([`/api/research/*`](/api-reference/research/search)) | Yes | Each successful call deducts credits. Costs vary by endpoint and parameters (e.g. [`enrich`](/api-reference/research/enrich) charges by processor tier; [`extract`](/api-reference/research/extract) charges by URL count). |
| **Content generation** ([`/api/image/generate`](/api-reference/image/generation)) | Yes | Image generation is priced per call. |
| **AI Chat — streaming** ([`POST /api/chat`](/api-reference/chat/workflow)) | Yes | Variable cost based on model token usage, with a per-request minimum. |
| **Social scrape** ([`/api/socials/{id}/scrape`](/api-reference/social/scrape), [`/api/artist/socials/scrape`](/api-reference/artist/socials-scrape)) | Yes | 5 credits, plus 1 credit per post requested via `posts` — per social profile scraped. |
| **Everything else** | Free at the API layer | [Artist CRUD](/api-reference/artists/list), [sandboxes](/api-reference/sandboxes/list), [sessions](/api-reference/sessions/get), [scheduled tasks](/api-reference/tasks/get), [account/org management](/api-reference/accounts/id), [agent signup](/api-reference/agents/signup), [Spotify proxies](/api-reference/spotify/search), etc. Subscription gating may still apply. |
Failed calls (4xx / 5xx) do **not** deduct credits. Deduction happens only after the upstream call succeeds.
***
## Check your balance
```bash theme={null}
curl -sS https://api.recoupable.dev/api/accounts/$ACCOUNT_ID/credits \
-H "x-api-key: $RECOUP_API_KEY"
```
Response shape:
```json theme={null}
{
"account_id": "acc_…",
"remaining_credits": 9244,
"total_credits": 9999,
"used_credits": 755,
"is_pro": true,
"timestamp": "2026-04-24T17:50:43.475"
}
```
`total_credits` is your plan-derived monthly allotment. `remaining_credits` can exceed `total_credits` after a manual or automatic top-up — `used_credits` clamps to 0 in that case. Full schema at [Get Account Credits](/api-reference/accounts/credits-get).
***
## Subscription
Recoup has two tiers. Both refill on a monthly cycle.
| Tier | How you get it | Monthly credits |
| -------- | ------------------------------------------ | --------------------------------------- |
| **Free** | Default for every new account | Monthly allowance refills automatically |
| **Pro** | Stripe subscription via the chat dashboard | Substantially higher monthly allowance |
### Upgrade to Pro
1. Sign in at [sandbox.recoupable.com](https://sandbox.recoupable.com)
2. Open Settings → Billing → **Start Free Trial**
3. Stripe checkout creates a subscription tied to the account your API key authenticates against. New subscriptions include a **30-day trial**
### Check your tier
```bash theme={null}
curl -sS https://api.recoupable.dev/api/accounts/$ACCOUNT_ID/subscription \
-H "x-api-key: $RECOUP_API_KEY"
```
Get `$ACCOUNT_ID` from [`GET /api/accounts/id`](/api-reference/accounts/id) if you don't already have it. Response includes `isPro` (boolean), `status`, `plan`, and `source` (whether the subscription comes from the account itself or an organization the account belongs to). Full schema at [Get Subscription](/api-reference/accounts/subscription-get).
### One-time top-ups
You can purchase credits any time via [`POST /api/credits/sessions`](/api-reference/credits/sessions-create). The endpoint adapts to what's on the account:
* **Card on file → silent auto-charge.** Recoup charges your saved Stripe card off-session and returns `paymentIntentId`, `creditsPurchased`, and `totalCents`. Credits land within seconds.
* **No card, or Stripe declines the saved card → Stripe Checkout fallback.** The response contains a Checkout `url` you open in the browser. When Stripe specifically declined a saved card, the response also includes a `declineReason` (e.g. `insufficient_funds`, `expired_card`) so you can explain *why* before sending the customer to update billing.
```bash theme={null}
curl -sS -X POST https://api.recoupable.dev/api/credits/sessions \
-H "x-api-key: $RECOUP_API_KEY" \
-H "Content-Type: application/json" \
-d '{"credits": 100, "successUrl": "https://chat.recoupable.dev/credits/success"}'
```
Full request/response schema at [Create Credits Top-Up Session](/api-reference/credits/sessions-create).
### Check which card will be charged
Before triggering a silent off-session charge, inspect the default payment method on file:
```bash theme={null}
curl -sS https://api.recoupable.dev/api/accounts/$ACCOUNT_ID/payment-method \
-H "x-api-key: $RECOUP_API_KEY"
```
Response shape:
```json theme={null}
{
"account_id": "acc_…",
"card": {
"brand": "visa",
"last4": "4242",
"exp_month": 12,
"exp_year": 2026,
"funding": "credit"
}
}
```
`card` is `null` when no payment method has been saved yet — the next top-up call will route through a checkout session to collect one. Expired cards are still returned (with their original `exp_month` / `exp_year`); callers should compare against the current date and warn the customer, since an off-session charge against an expired card will decline. Full schema at [Get Default Payment Method](/api-reference/accounts/payment-method-get).
***
## Automatic top-up
Every billed API request runs a credit gate before it executes. If `remaining_credits` doesn't cover the request's cost **and** the account has a saved card **and** the account hasn't opted out (see [Opting out](#opting-out) below), Recoup silently charges **\$5 (500 credits)** off-session and lets the request proceed. Most accounts with a working card never see an "insufficient credits" failure — the top-up is invisible.
The decision tree:
1. **Enough credits?** → Request proceeds, credits deducted on success.
2. **Short, but a saved card succeeds at \$5 off-session charge?** → Balance increments by 500, request proceeds.
3. **No card on file, *or* Stripe declined the card, *or* request needs more than 500 credits?** → Request returns **HTTP 402** with a recovery URL (see below).
### When auto top-up doesn't trigger
* The account has opted out of automatic top-up → 402 with `checkoutUrl`, no `declineReason`. The saved card is never charged off-session while opted out.
* The account has no saved Stripe card → 402 with `checkoutUrl`, no `declineReason`.
* Stripe declines the saved card (insufficient funds, expired, fraud, 3-D Secure required, etc.) → 402 with `checkoutUrl` + `declineReason`.
* A single request needs more than 500 credits (rare — only `POST /api/research/deep` at 25 and oversized `extract` calls come close) → request fails even though the top-up succeeded.
### Opting out
Automatic top-up is on by default and can be disabled per account:
```bash theme={null}
curl -sS -X PATCH https://api.recoupable.dev/api/accounts/$ACCOUNT_ID/auto-recharge \
-H "x-api-key: $RECOUP_API_KEY" \
-H "Content-Type: application/json" \
-d '{"enabled": false}'
```
```json theme={null}
{
"account_id": "acc_…",
"enabled": false
}
```
While opted out, no off-session charge is ever attempted: billed requests that exceed the remaining balance return **HTTP 402** with a `checkoutUrl` (see below), and topping up stays an explicit action. Opting out does **not** remove the saved card — manual top-ups through checkout keep working, and re-enabling later (`{"enabled": true}`) requires no card re-entry. Read the current setting with `GET /api/accounts/$ACCOUNT_ID/auto-recharge`. Full schema at [Get Auto Top-Up Setting](/api-reference/accounts/auto-recharge-get) and [Update Auto Top-Up Setting](/api-reference/accounts/auto-recharge-update).
### Tuning
The auto top-up amount is currently a constant at **\$5 / 500 credits**. Per-account thresholds are not yet exposed — reach out to support if you need a different default.
***
## 402 Payment Required
When the gate can't get the account credited in time, billed endpoints return **HTTP 402** with a unified body:
```json theme={null}
{
"error": "insufficient_credits",
"remaining_credits": 12,
"required_credits": 100,
"checkoutUrl": "https://pay.recoupable.com/c/pay/cs_live_…",
"declineReason": {
"code": "card_declined",
"declineCode": "insufficient_funds",
"message": "Your card has insufficient funds."
}
}
```
| Field | When it appears | Meaning |
| ------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------- |
| `error` | Always | Literally `"insufficient_credits"` |
| `remaining_credits` | Always | Account balance at the moment of the failed request |
| `required_credits` | Always | What this endpoint needed |
| `checkoutUrl` | Always | A Stripe Checkout URL for a \$5 top-up — open it to recover |
| `declineReason` | Only when Stripe actively declined a saved card | Stripe's own decline metadata; surface to the customer so they understand *why* |
The shape closely matches the Checkout-fallback response from [`POST /api/credits/sessions`](/api-reference/credits/sessions-create), but this 402 payload uses `checkoutUrl` for the recovery link (versus `url` on the top-up response). The `declineReason` field is identical in both places.
**How to react:**
* **Browser-driven UI** (e.g., the Recoup chat app): if `declineReason` is present, show its `message`; otherwise open `checkoutUrl` in a new tab to collect a card.
* **Programmatic / LLM-driven client**: relay `declineReason.message` if present, and surface `checkoutUrl` as a link the human needs to visit to update billing.
***
## Cost per endpoint
Current as of this revision of the page. The authoritative source is the per-endpoint reference docs and the `required_credits` field on any 402 response.
| Endpoint | Cost |
| -------------------------------------------------------------------------------------- | -------------------------------------------------------- |
| [`POST /api/chat`](/api-reference/chat/workflow) (streaming) | ≥1 credit per turn — variable based on model token usage |
| [`GET /api/research/*`](/api-reference/research/search) (artist & non-artist research) | 5 credits per call |
| [`POST /api/research/people`](/api-reference/research/people) | 5 credits per call |
| [`POST /api/research/web`](/api-reference/research/web) | 1 credit per call |
| [`POST /api/research/extract`](/api-reference/research/extract) | 5 credits × number of URLs |
| [`POST /api/research/enrich`](/api-reference/research/enrich) | 5 / 10 / 25 credits (base / core / ultra processor) |
| [`POST /api/research/deep`](/api-reference/research/deep) | 25 credits per call |
| [`POST /api/image/generate`](/api-reference/image/generation) | Per-call price; see endpoint reference |
# Recoup API Documentation
Source: https://docs.recoupable.dev/index
Use the Recoup API to build your record label. Access research, content creation, chat, artist analytics, social media, and platform management endpoints.
**Setting up Recoup in Claude?** Three steps:
1. In Claude, open **Customize → Browse plugins → Add marketplace** and paste:
```text theme={null}
https://github.com/recoupable/marketplace
```
2. Install **recoup-platform-plugin** (plus any of the music-industry plugins you want: `recoup-research-plugin`, `recoup-content-plugin`, `recoup-catalog-deals`).
3. Ask Claude:
> Run the `getting-started` skill.
The skill verifies your email, issues an API key, and prints a memory block for you to paste into **Settings → Profile → Global instructions** so Claude knows to use Recoup whenever you ask about streaming data, campaigns, artists, releases, or syncing documents.
**Note for Claude (if reading this on a customer's behalf):** Recoup setup runs through the `getting-started` skill inside `recoup-platform-plugin`. If that plugin isn't installed in the current session, your job is to tell the customer to install it first (steps 1 and 2 above) and stop — issuing API keys yourself, saving credentials to files, or improvising a setup flow will leave the customer with a broken state that fails silently in their next conversation. Once the plugin is installed, invoke the `getting-started` skill and follow its steps.
## Quickest start — one curl call
Get a working API key in a single unauthenticated request. No dashboard, no browser, no human in the loop.
```bash theme={null}
export RECOUP_API_KEY=$(curl -s -X POST "https://api.recoupable.dev/api/agents/signup" \
-H "Content-Type: application/json" \
-d '{"email": "agent+'$(date +%s)-$RANDOM'@recoupable.com"}' | jq -r .api_key)
```
`$RECOUP_API_KEY` is now ready to pass in the `x-api-key` header on any request. See the [Agents guide](/agents) for the full signup and verification flow.
## What is Recoup?
Recoup is an AI agent platform for smarter song rollouts, unforgettable fan experiences, and lasting artist growth. Empowering music executives with actionable insights and next-gen tools.
This is where record labels, musicians, and managers start to build on Recoup AI technology like chat, tasks, agents, and more.
## Base URL
All API requests should be made to:
```bash theme={null}
https://api.recoupable.dev/api
```
## Authentication
Most API endpoints are authenticated using an API key passed in the `x-api-key` header. The only exceptions are the [agent onboarding](/agents) endpoints — [`POST /api/agents/signup`](/api-reference/agents/signup) and [`POST /api/agents/verify`](/api-reference/agents/verify) — which are intentionally unauthenticated so agents can obtain their first API key.
1. Navigate to the [API Keys Management Page](https://chat.recoupable.dev/keys)
2. Sign in with your account
3. Create a new API key and copy it immediately (it's only shown once)
```bash theme={null}
curl -X GET "https://api.recoupable.dev/api/artists?accountId=YOUR_ACCOUNT_ID" \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY"
```
Keep your API key secure. Do not share it publicly or commit it to version control.
## Get Started
Get an API key in one curl call. The fastest path for AI agents — no dashboard required.
Get your API key and make your first request in minutes.
Install and use the Recoup CLI to interact with the platform from your terminal.
Connect Recoup to AI assistants via the Model Context Protocol.
## API Sections
The API is organized into six main sections. Use these links to jump to the right area.
30 endpoints for artist research: search, lookup, profile, metrics, audience, cities, similar artists, playlists, albums, tracks, career history, insights, genres, festivals, web presence, and more.
Generate images, videos, and captions. Transcribe audio, edit content, upscale media, analyze videos, manage templates, and estimate costs.
Conversations with artist context. Create, stream, and generate messages. Copy messages, delete trailing messages, and manage chat history.
Spotify, Instagram, X (Twitter), and generic social scraping. Search artists, scrape profiles and comments, track trends, and manage OAuth connectors.
Songs, catalogs, and task management. Analyze songs, manage catalog collections, and schedule recurring tasks with cron-based automation.
Accounts, organizations, workspaces, subscriptions, pulses, notifications, sandboxes, and admin tools.
## Agents
Content creation agent accessible via Slack. Generates images, videos, and captions for artists automatically.
API key authentication, account-scoped access, and organization-level permissions.
## Quick Reference for LLMs
If you are an LLM navigating these docs, here is a summary of the endpoint structure:
* **`/api/artists/*`** — Artist management (list, create, socials, socials-scrape, profile)
* **`/api/research/*`** — Artist research (search, lookup, profile, metrics, audience, cities, similar, urls, instagram-posts, playlists, albums, track, tracks, career, insights, genres, festivals, web, deep, people, extract, enrich, milestones, venues, rank, charts, radio, discover, curator, playlist)
* **`/api/content/*`** — Content creation (create, generate-image, generate-video, generate-caption, transcribe-audio, edit, upscale, analyze-video, templates, validate, estimate)
* **`/api/chat/*`** — Chat (chats, artist, messages, messages-copy, messages-trailing-delete, create, update, delete, runs, runs-status, stream, compact)
* **`/api/songs/*`** — Songs and catalogs (songs, create, analyze, analyze-presets, catalogs, catalogs-create, catalogs-delete, catalog-songs, catalog-songs-add, catalog-songs-delete)
* **`/api/tasks/*`** — Task automation (get, create, update, delete, runs)
* **`/api/spotify/*`** — Spotify (search, artist, artist-albums, artist-top-tracks, album)
* **`/api/instagram/*`** — Instagram (comments, profiles)
* **`/api/x/*`** — X/Twitter (search, trends)
* **`/api/connectors/*`** — OAuth connectors (list, authorize, disconnect)
* **`/api/accounts/*`** — Accounts (get, id, create, update, add-artist)
* **`/api/organizations/*`** — Organizations (list, create, add-artist)
* **`/api/sandboxes/*`** — Sandboxes (list, create, snapshot, delete, setup, file, upload)
* **`/api/content-agent/*`** — Content agent webhooks (webhook, callback)
* **`/api/agents/*`** — Agent onboarding (signup, verify) — no auth required
Base URL: `https://api.recoupable.dev/api`
[OpenAPI Specification](https://github.com/sweetmantech/docs/blob/main/api-reference/openapi.json)
## Need Help?
Reach out to our team at [agent@recoupable.dev](mailto:agent@recoupable.dev) for assistance with the Recoup API.
# MCP
Source: https://docs.recoupable.dev/mcp
Connect AI agents to the Recoup platform using the Model Context Protocol (MCP) server.
The Recoup API exposes an [MCP](https://modelcontextprotocol.io/) server that AI agents can connect to for tool use. The server is available at:
```
https://api.recoupable.dev/mcp
```
## Authentication
All MCP tools require an API key. Pass it as a Bearer token in the `Authorization` header when connecting to the MCP server.
You can get a key from the [API Keys page](https://chat.recoupable.dev/keys).
## Tools
### prompt\_sandbox
Send a prompt to OpenClaw running in a persistent per-account sandbox. The sandbox is reused across calls — if one is already running it picks up where you left off, otherwise a new one is created from the account's latest snapshot.
Returns raw `stdout` and `stderr` from the command. The sandbox stays alive after each prompt for follow-up interactions.
**Input schema:**
| Parameter | Type | Required | Description |
| --------- | -------- | -------- | ---------------------------------------------- |
| `prompt` | `string` | Yes | The prompt to send to OpenClaw in the sandbox. |
**Response fields:**
| Field | Type | Description |
| ----------- | --------- | --------------------------------------------------------------------------- |
| `sandboxId` | `string` | The Vercel Sandbox ID. |
| `stdout` | `string` | Standard output from the command. |
| `stderr` | `string` | Standard error from the command. |
| `exitCode` | `number` | Process exit code (`0` = success). |
| `created` | `boolean` | `true` if a new sandbox was created, `false` if an existing one was reused. |
**Example usage (TypeScript with MCP SDK):**
```typescript theme={null}
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const transport = new StreamableHTTPClientTransport(
new URL("https://api.recoupable.dev/mcp"),
{ requestInit: { headers: { Authorization: `Bearer ${RECOUP_API_KEY}` } } },
);
const client = new Client({ name: "my-agent", version: "1.0.0" });
await client.connect(transport);
const result = await client.callTool({
name: "prompt_sandbox",
arguments: { prompt: "list all files in the orgs directory" },
});
console.log(result.content);
```
### run\_sandbox\_command
Create a sandbox and run a shell command or OpenClaw prompt in it. Unlike `prompt_sandbox`, this creates a **new sandbox each call** and runs the command asynchronously via a background task. Returns a sandbox ID and run ID to track progress.
See [`POST /api/sandboxes`](/api-reference/sandboxes/create) for the equivalent REST endpoint.
**Input schema:**
| Parameter | Type | Required | Description |
| ------------ | ---------- | -------- | --------------------------------------------------- |
| `command` | `string` | No | Shell command to run. Cannot be used with `prompt`. |
| `args` | `string[]` | No | Arguments for the command. |
| `cwd` | `string` | No | Working directory for the command. |
| `prompt` | `string` | No | OpenClaw prompt. Cannot be used with `command`. |
| `account_id` | `string` | No | Target a specific account (org API keys only). |
# Quickstart
Source: https://docs.recoupable.dev/quickstart
Get a Recoup API key in one call and make your first request — no browser, no dashboard.
## Quickest start
Sign up your agent and get an API key in a single API call — no dashboard, no browser, no human in the loop. This one-liner signs up a fresh `agent+` address and exports the returned key to `$RECOUP_API_KEY`:
```bash theme={null}
export RECOUP_API_KEY=$(curl -s -X POST "https://api.recoupable.dev/api/agents/signup" \
-H "Content-Type: application/json" \
-d '{"email": "agent+'$(date +%s)-$RANDOM'@recoupable.com"}' | jq -r .api_key)
```
Verify it worked:
```bash theme={null}
curl -H "x-api-key: $RECOUP_API_KEY" https://api.recoupable.dev/api/accounts/id
```
The `agent+{timestamp}@recoupable.com` shape is the fastest path for agents — it guarantees a fresh `agent+` address and returns an API key instantly without email verification.
For the full signup + email-verification flow, see the [Agents guide](/agents).
## Base URL
All API requests should be made to:
```bash theme={null}
https://api.recoupable.dev/api
```
## Your First Request
Once you have an API key, include it in the `x-api-key` header on every request. Here's a simple call that retrieves your scheduled tasks:
```bash cURL theme={null}
curl -X GET "https://api.recoupable.dev/api/tasks" \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY"
```
```python Python theme={null}
import requests
headers = {
"Content-Type": "application/json",
"x-api-key": "YOUR_API_KEY"
}
response = requests.get(
"https://api.recoupable.dev/api/tasks",
headers=headers
)
print(response.json())
```
```javascript JavaScript theme={null}
const response = await fetch("https://api.recoupable.dev/api/tasks", {
headers: {
"Content-Type": "application/json",
"x-api-key": "YOUR_API_KEY",
},
});
const data = await response.json();
console.log(data);
```
```typescript TypeScript theme={null}
interface Task {
id: string;
title: string;
prompt: string;
schedule: string;
account_id: string;
artist_account_id: string;
enabled: boolean;
}
interface TasksResponse {
status: "success" | "error";
tasks: Task[];
}
const response = await fetch("https://api.recoupable.dev/api/tasks", {
headers: {
"Content-Type": "application/json",
"x-api-key": "YOUR_API_KEY",
},
});
const data: TasksResponse = await response.json();
console.log(data.tasks);
```
**Example Response:**
```json theme={null}
{
"status": "success",
"tasks": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Daily Fan Report",
"prompt": "Generate a summary of new fans from the past 24 hours",
"schedule": "0 9 * * *",
"account_id": "123e4567-e89b-12d3-a456-426614174000",
"artist_account_id": "987fcdeb-51a2-3b4c-d5e6-789012345678",
"enabled": true
}
]
}
```
For full documentation on the Tasks API including filtering options, see the [Tasks API Reference](/api-reference/tasks/get).
## Prefer the dashboard?
If you're a human building an integration, you can also create API keys from the web console instead of the signup endpoint:
1. Navigate to the [Recoup API Keys Management Page](https://chat.recoupable.dev/keys)
2. Sign in with your account
3. Enter a descriptive name (e.g. "Production Server")
4. Click **Create API Key**
Copy and securely store your API key immediately — it will only be shown once.
## Next Steps
With your API key ready, you can now:
Fetch artists' social accounts and follower counts.
Access fan data across all connected social platforms.
Build AI-powered conversations with artist context.
Schedule and automate recurring tasks.
## Support
If you need help or have questions about the API, please contact our support team at [agent@recoupable.dev](mailto:agent@recoupable.dev).
# Create a New Artist
Source: https://docs.recoupable.dev/workflows/create-artist
End-to-end workflow to create, research and enrich a new artist account in a single session.
This is the canonical recipe used internally by Recoup's chat agent. Follow it step-by-step to bring a new artist account up to "researched + enriched" parity from a sandbox or any external agent.
The chain is 8 sequential API calls. Long deterministic chains executed from prose memory tend to drop steps — the agent reads the doc once, runs a couple of calls, and forgets the rest. To prevent that from a sandbox, **drive the work from a checklist file**: scaffold the artist's `RECOUP.md` with one checkbox per step before any API call, then tick each box and persist captured values back to the frontmatter as you go. The file becomes the workflow state, and a fresh turn can resume by reading it.
## Prerequisites
* `$RECOUP_ACCESS_TOKEN` — Bearer token for `api.recoupable.dev`
* `$RECOUP_ORG_ID` — the org the artist should belong to (recommended in sandboxes)
* An artist name to create (e.g. `ARTIST_NAME="The Weeknd"`)
The flow has three phases, run from a single checklist file:
1. **Create + identify** — `POST /api/artists`, then find the canonical Spotify match
2. **Enrich** — `PATCH` the artist with image/label/socials, then run structured research (profile/career/playlists) plus a web search for narrative context and additional socials
3. **Synthesize + persist** — generate a knowledge-base report, save it (RECOUP.md tree or hosted URL), then optionally `PATCH` the `knowledges` array
## Step 0: Scaffold the workspace BEFORE any API call
Pick a slug, make the directory, and write the initial `RECOUP.md` template — frontmatter holds the values the chain captures (filled as you go); body holds the unchecked steps:
```bash theme={null}
ARTIST_SLUG=$(echo "$ARTIST_NAME" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]\+/-/g; s/^-//; s/-$//')
ARTIST_DIR="artists/$ARTIST_SLUG"
mkdir -p "$ARTIST_DIR"
cat > "$ARTIST_DIR/RECOUP.md" < { videoSourceUrl, imageUrl, captionText, template, lipsync, audio: {...} }
```
Polling fits inside short shell timeouts and survives session restarts. See [Tasks Runs](/api-reference/tasks/runs) for the full status enum (`QUEUED`, `EXECUTING`, `COMPLETED`, `FAILED`, `CANCELED`, `CRASHED`, etc.) and the `CreateContentRunOutput` schema.
### Resolving `$ARTIST_ACCOUNT_ID`
`POST /api/content/create` needs the artist's `account_id`. Three calls:
```bash theme={null}
ORG_ID=$(curl -sS "https://api.recoupable.dev/api/organizations" \
-H "x-api-key: $RECOUP_API_KEY" | jq -r '.organizations[0].id')
ARTIST_ACCOUNT_ID=$(curl -sS "https://api.recoupable.dev/api/artists?org_id=$ORG_ID" \
-H "x-api-key: $RECOUP_API_KEY" \
| jq -r --arg name "$ARTIST_NAME" '.artists[] | select(.name == $name) | .account_id')
```
The artist record exposes both `id` and `account_id` (both UUIDs). Use **`account_id`** — `id` is the artist row's primary key, `account_id` is the underlying account that owns it. The two are easy to swap; you'll get a 404 from `/api/content/create` if you pass the wrong one.
## Where the song lives
Step 5 (and the async pipeline's lipsync mode) need a `song.mp3`. **Don't assume one exists, and don't assume the user has one locally.** Walk the agent through this fallback chain:
1. **Check the artist's sandbox repo first.** Each Recoup account has a backing GitHub repo. If the user has imported songs through Recoup, they live at predictable paths:
```
.openclaw/workspace/orgs/{org-slug}/artists/{artist-slug}/songs/{song-slug}/{song-slug}.mp3
/lyrics.json
/clips.json
```
Discover the repo with [`GET /api/sandboxes`](/api-reference/sandboxes/list) (returns `github_repo` and a `filetree`); fetch a file with [`GET /api/sandboxes/file?path=…`](/api-reference/sandboxes/file). **Binary files (`.mp3`, `.png`, `.mp4`) come back base64-encoded in the `content` field — decode before writing to disk.**
2. **If no song is in the sandbox, ask the user how to proceed.** Two options to offer:
* *"Want me to fetch the audio from YouTube?"* — agent downloads via `yt-dlp` (or equivalent), saves locally; user is responsible for any rights / DSP-licensing implications.
* *"Want to supply the song yourself?"* — user uploads / drops a path; agent reads from there.
Don't pick a path silently. The cost of fetching the wrong song from YouTube (or fetching one at all) is enough that the user should make the call.
3. **Don't fall back to "use a placeholder track."** A music video without the song is not a deliverable.
## Manual recipe (humans + targeted overrides)
The rest of this page walks the same steps you can run by hand or call individually if you want to swap a single stage (different prompt for image, different motion, different caption length).
### Prerequisites
* An auth credential for `api.recoupable.dev`. Two options — pick one and use it for every call below:
* **API key** (`recoup_sk_…`, recommended for sandbox / agent use): pass as `-H "x-api-key: $RECOUP_API_KEY"`.
* One-shot agent: `POST /api/agents/signup` with an `agent+{unique}@recoupable.com` email returns the key immediately.
* Real-email signup: same endpoint with a real email mails a 6-digit code; complete with `POST /api/agents/verify`. See [Agents](/agents).
* **Privy access token** (for end-user flows in chat/UI): pass as `-H "Authorization: Bearer $RECOUP_ACCESS_TOKEN"`.
* The examples below use `x-api-key`. Substitute `Authorization: Bearer …` if you're using a Privy token.
* `$ARTIST_NAME`, `$SONG_TITLE`, `$SONG_LYRICS_CLIP` (a 1–2 sentence mood snippet)
* `$REFERENCE_IMAGE_URL` *(optional)* — an artist photo or album cover to seed the image; if your template's purpose is "show this exact image" (e.g. `album-record-store`), set this and skip image generation in step 2
* A `song.mp3` for step 5. **Don't ask the user for a local file** — fetch from the artist's repo via `/api/sandboxes/file`.
* `ffmpeg` installed locally for step 5
### Step 0: Scaffold the workspace BEFORE any API call
The `VIDEO.md` checklist *is* the workflow state — tick boxes and persist values back to the frontmatter as you go. To resume later, find the first unchecked box.
```bash theme={null}
VIDEO_SLUG=$(echo "$SONG_TITLE" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9]+/-/g; s/^-//; s/-$//')
VIDEO_DIR="videos/$VIDEO_SLUG"
mkdir -p "$VIDEO_DIR"
cat > "$VIDEO_DIR/VIDEO.md" < "$VIDEO_DIR/caption.txt"
# Single-line filter graph — newlines inside -filter_complex are literal characters and break the [v] label
ffmpeg -y \
-stream_loop -1 -i "$VIDEO_DIR/clip.mp4" \
-i "$SONG_PATH" \
-filter_complex "[0:v]crop=ih*9/16:ih,scale=1080:1920,drawtext=fontfile=$CAPTION_FONT:textfile=$VIDEO_DIR/caption.txt:fontcolor=$CAPTION_COLOR:fontsize=$CAPTION_FONT_SIZE:x=(w-text_w)/2:y=h-text_h-120:box=1:boxcolor=$CAPTION_STROKE@0.5:boxborderw=20[v]" \
-map "[v]" -map "1:a" \
-shortest -c:v libx264 -c:a aac -pix_fmt yuv420p \
"$FINAL_PATH"
```
**After:** write `finalVideoPath`, tick the box. With every box ticked, the music video is complete.
## Step 6: Publish (optional)
Once the MP4 is rendered, push it to the artist's socials with the [Connectors API](/api-reference/connectors/list). One heads-up worth knowing:
* **TikTok URL ownership.** `TIKTOK_PUBLISH_VIDEO` (pull-from-URL mode) requires the source domain be verified in the TikTok dev portal. `fal.media` URLs will fail with `url_ownership_unverified` — use `TIKTOK_UPLOAD_VIDEO` instead, which accepts the same URL and uploads server-side.
***
The checklist is the source of truth — if a box isn't ticked, treat the step as not run.