-
Notifications
You must be signed in to change notification settings - Fork 3
feat: docs design overhaul — achromatic design system + narrative alignment #128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
sidneyswift
wants to merge
24
commits into
main
Choose a base branch
from
feature/docs-design-overhaul
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
77c0e76
feat: redesign docs with achromatic design system and sharper narrative
sidneyswift d66dd2a
feat: rethink docs taxonomy around agent workflows
sidneyswift 712783b
refactor: split Catalog tab, move Connectors to Accounts, standardize…
sidneyswift 28e52ee
fix: use "endpoints" in technical docs, keep "tools" in marketing/MCP…
sidneyswift c78318f
feat: add problem statement, core concepts, how-it-works flow, rename…
sidneyswift 97c2052
feat: rebuild Agent Onboarding as operating manual, tighten homepage
sidneyswift 6ba14ca
fix: correct agent+ email documentation — they create separate accounts
sidneyswift 691e3a3
fix: deprecate content pipeline, promote individual endpoints
sidneyswift 0c4fd25
polish: tighten copy, rename Automation→Tasks, move Sandboxes→Accounts
sidneyswift 87adf00
polish: simplify core concepts, refine copy throughout
sidneyswift f5d587b
feat: give Chat its own tab — it's the conversational AI layer, not r…
sidneyswift e167c4f
rename: Tasks → Automation
sidneyswift 02d48d2
polish: bigger logo, human not user, Automation tab name
sidneyswift 1a24534
fix: use ?artist= not ?q= for research/metrics, audience, playlists e…
sidneyswift d40b6d4
fix: add 10 missing endpoint groups to LLM endpoint map
sidneyswift 65defe5
fix: adjust dark accent color for better button contrast in dark mode
sidneyswift 0496630
fix: restore POST /api/sandboxes link in CLI docs
sidneyswift c978054
fix: restore POST /api/chats link in CLI docs
sidneyswift d68be44
fix: clarify that instant key issuance is specific to agent+ email pa…
sidneyswift b5b17cd
fix: content endpoints card links to generate-image, not legacy pipeline
sidneyswift 3f70b34
fix: rename Primitive column header to Endpoint in content-agent
sidneyswift 16b7bbc
fix: add era.json to filesystem directory tree
sidneyswift 02d761c
fix: move deprecation from MDX warning to OpenAPI deprecated field
sidneyswift f0abb37
fix: add specific endpoint names to deprecation notice in OpenAPI spec
sidneyswift File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,96 +1,146 @@ | ||
| --- | ||
| title: 'Agents' | ||
| description: 'Programmatic agent onboarding — sign up and obtain API keys in one call, no dashboard, no human in the loop.' | ||
| title: "Agent Onboarding" | ||
| description: "The operating manual for AI agents using the Recoupable API." | ||
| --- | ||
|
|
||
| ## Quickest start | ||
| This page is for AI agents. Follow these steps in order. | ||
|
|
||
| ## 1. Authenticate | ||
|
|
||
| If your human has an API key, pass it via `x-api-key`. If not, generate one: | ||
|
|
||
| <Steps> | ||
| <Step title="Call signup with their email"> | ||
| ```bash | ||
| curl -X POST "https://recoup-api.vercel.app/api/agents/signup" \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{"email": "user@example.com"}' | ||
| ``` | ||
| </Step> | ||
| <Step title="Ask the human for the code"> | ||
| A 6-digit code was sent to their inbox. Ask them: *"Check your email for a verification code and share it with me."* | ||
| </Step> | ||
| <Step title="Call verify with the code"> | ||
| ```bash | ||
| curl -X POST "https://recoup-api.vercel.app/api/agents/verify" \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{"email": "user@example.com", "code": "123456"}' | ||
| ``` | ||
| Store the returned `api_key`. Pass it as `x-api-key` on every request. | ||
| </Step> | ||
| </Steps> | ||
|
|
||
| **After authenticating, immediately check the roster.** Don't wait for the human to tell you what to do. | ||
|
|
||
| <Warning> | ||
| `agent+` emails create a **separate account** — `agent+user@example.com` is NOT linked to `user@example.com`. To work on behalf of an existing human, use their real email. | ||
| </Warning> | ||
|
|
||
| Get a working API key in a single unauthenticated request: | ||
|
|
||
| ```bash | ||
| curl -X POST "https://recoup-api.vercel.app/api/agents/signup" \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{"email": "agent+'$(date +%s)-$RANDOM'@recoupable.com"}' | ||
| ``` | ||
|
|
||
| Response: | ||
|
|
||
| ```json | ||
| { | ||
| "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. | ||
| ## 2. Understand the roster | ||
|
|
||
| <Tip> | ||
| **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: | ||
| After getting a key, your next call should always be to check what the human has: | ||
|
|
||
| ```bash | ||
| export RECOUP_API_KEY=$(curl -s -X POST "https://recoup-api.vercel.app/api/agents/signup" \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{"email": "agent+'$(date +%s)-$RANDOM'@recoupable.com"}' | jq -r .api_key) | ||
| # List all artists available to this account | ||
| curl "https://recoup-api.vercel.app/api/artists" \ | ||
| -H "x-api-key: $API_KEY" | ||
|
|
||
| # List organizations (labels/teams) the account belongs to | ||
| curl "https://recoup-api.vercel.app/api/organizations" \ | ||
| -H "x-api-key: $API_KEY" | ||
| ``` | ||
|
|
||
| Verify it worked: | ||
| **If the human has artists**, you can scope work to a specific artist by passing `artist_account_id` on supported endpoints. Research, content, tasks, and fan segments all become artist-specific. | ||
|
|
||
| ```bash | ||
| curl -H "x-api-key: $RECOUP_API_KEY" https://recoup-api.vercel.app/api/accounts/id | ||
| ``` | ||
| </Tip> | ||
| **If the human has organizations**, pass `organization_id` to scope to a specific label's roster. | ||
|
|
||
| <Tip> | ||
| 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. | ||
| </Tip> | ||
| **If neither is specified**, you operate at the account level and can see everything available to the human. | ||
|
|
||
| ## How it works | ||
| --- | ||
|
|
||
| Two unauthenticated endpoints power agent onboarding: | ||
| ## 3. Know the filesystem | ||
|
|
||
| - **[`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. | ||
| Each account has a persistent filesystem backed by a GitHub repo. This is where artist context lives — the files agents use to do informed work. | ||
|
|
||
| Multiple API keys per account are supported — each signup or verification generates a new key without revoking existing ones. | ||
| ### Artist directory structure | ||
|
|
||
| ## Standard signup (email verification) | ||
| ``` | ||
| orgs/{org-name}/artists/{artist-slug}/ | ||
| ├── RECOUP.md # Identity file (artistName, artistSlug, artistId) | ||
| ├── context/ | ||
| │ ├── artist.md # Brand voice, bio, constraints | ||
| │ ├── audience.md # Audience insights, resonance | ||
| │ ├── era.json # Current era metadata | ||
| │ └── images/ | ||
| │ └── face-guide.png # Face reference for visual content | ||
| ├── songs/{song-slug}/ | ||
| │ └── {song-slug}.mp3 # Audio files | ||
| ├── releases/{release-slug}/ | ||
| │ └── RELEASE.md # Release plan and metadata | ||
| └── config/ | ||
| └── content-creation/ | ||
| └── config.json # Pipeline overrides | ||
| ``` | ||
|
|
||
| If you're building a human-facing integration and want the user to verify their real email, use any non-`agent+` address: | ||
| The `RECOUP.md` file ties the folder to the platform — it contains YAML frontmatter with `artistName`, `artistSlug`, and `artistId`. | ||
|
|
||
| Step 1 — request a verification code: | ||
| ### Accessing sandbox files | ||
|
|
||
| ```bash | ||
| curl -X POST "https://recoup-api.vercel.app/api/agents/signup" \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{"email": "you@example.com"}' | ||
| ``` | ||
| # List the full file tree | ||
| curl "https://recoup-api.vercel.app/api/sandboxes" \ | ||
| -H "x-api-key: $API_KEY" | ||
|
|
||
| Step 2 — submit the 6-digit code from the verification email: | ||
| # Read a specific file | ||
| curl "https://recoup-api.vercel.app/api/sandboxes/file?path=orgs/my-label/artists/drake/context/artist.md" \ | ||
| -H "x-api-key: $API_KEY" | ||
|
|
||
| ```bash | ||
| curl -X POST "https://recoup-api.vercel.app/api/agents/verify" \ | ||
| # Upload files to the repo | ||
| curl -X POST "https://recoup-api.vercel.app/api/sandboxes/files" \ | ||
| -H "x-api-key: $API_KEY" \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{"email": "you@example.com", "code": "123456"}' | ||
| -d '{"files": [{"url": "https://...", "path": "orgs/my-label/artists/drake/context/audience.md"}]}' | ||
| ``` | ||
|
|
||
| Response: | ||
| --- | ||
|
|
||
| ```json | ||
| { | ||
| "account_id": "123e4567-e89b-12d3-a456-426614174000", | ||
| "api_key": "recoup_sk_abc123...", | ||
| "message": "Verified" | ||
| } | ||
| ``` | ||
| ## 4. Decide what to do | ||
|
|
||
| ## Using your API key | ||
| <Steps> | ||
| <Step title="Does the human have a roster?"> | ||
| Call `GET /api/artists`. If they have artists, list them and ask which one to work with. If not, you can research any artist with `GET /api/research?q=...` or create one with `POST /api/artists`. | ||
| </Step> | ||
| <Step title="What kind of work?"> | ||
| **Research** — use the 30+ research endpoints. Pass `artist_account_id` to scope to a rostered artist, or search by name for any artist globally. | ||
|
|
||
| Pass the returned `api_key` in the `x-api-key` header on every authenticated request: | ||
| **Content** — generate images, videos, and captions with the content endpoints. Artist context from the filesystem makes output more on-brand. | ||
|
|
||
| ```bash | ||
| curl -X GET "https://recoup-api.vercel.app/api/tasks" \ | ||
| -H "x-api-key: YOUR_API_KEY" | ||
| **Manage** — plan and track releases by creating and updating `RELEASE.md` files in the artist's `releases/` directory. Add songs to catalogs, update artist context, and organize the roster. | ||
| </Step> | ||
| <Step title="Should you save the work?"> | ||
| Save research, generated content, or notes to the artist's directory in the filesystem so future calls have more context. Use `POST /api/sandboxes/files` to upload files to the repo. | ||
| </Step> | ||
| <Step title="Should this be recurring?"> | ||
| If the human asks for something more than once, or if the work is time-sensitive and repeating, turn it into a task with `POST /api/tasks`. | ||
|
|
||
| Good candidates for tasks: | ||
| - Daily or weekly reports (streaming stats, fan growth, playlist adds) | ||
| - Monitoring competitors or trending artists | ||
| - Generating recurring content (weekly social posts, monthly recaps) | ||
| - Checking release milestones as a date approaches | ||
|
|
||
| If the human only needs it once, just do it. Don't create a task for everything. | ||
| </Step> | ||
| </Steps> | ||
|
|
||
| --- | ||
|
|
||
| ## Base URL | ||
|
|
||
| ``` | ||
| https://recoup-api.vercel.app/api | ||
| ``` | ||
|
|
||
| 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. | ||
| All endpoints require `x-api-key` header unless noted. See [Authentication](/authentication) for the full auth model, and the [endpoint map](/#for-ai-agents) for every available endpoint. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,115 +1,106 @@ | ||
| --- | ||
| title: "Authentication" | ||
| description: "How authentication works in the Recoup API — API keys, access tokens, and organization access control." | ||
| description: "API keys and Bearer tokens — how to authenticate every request to the Recoup API." | ||
| --- | ||
|
|
||
| ## Overview | ||
| **Use API keys** for server-to-server, CLI, and agent integrations. **Use Bearer tokens** for frontend apps authenticated via Privy. Include exactly one — providing both returns `401`. | ||
|
|
||
| Every request to the Recoup API must be authenticated using exactly one of two mechanisms: | ||
|
|
||
| | Method | Header | Use case | | ||
| | Method | Header | Best for | | ||
| |--------|--------|----------| | ||
| | API Key | `x-api-key` | Server-to-server integrations | | ||
| | Access Token | `Authorization: Bearer <token>` | Frontend apps authenticated via Privy | | ||
|
|
||
| Providing both headers in the same request will result in a `401` error. | ||
| | API Key | `x-api-key` | Servers, scripts, CLI, AI agents | | ||
| | Bearer Token | `Authorization: Bearer <jwt>` | Frontend apps via Privy | | ||
|
|
||
| <Note> | ||
| 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. | ||
| [Agent signup](/agents) endpoints are unauthenticated — they let agents get their first key without any credentials. | ||
| </Note> | ||
|
|
||
| --- | ||
|
|
||
| ## API Keys | ||
| ## Create a key | ||
|
|
||
| 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. | ||
| ### Instant (for agents) | ||
|
|
||
| ### Creating an API Key | ||
| One call, no verification: | ||
|
|
||
| 1. Navigate to [chat.recoupable.com/keys](https://chat.recoupable.com/keys) | ||
| 2. Enter a descriptive name (e.g. `"Production Server"`) | ||
| 3. Click **Create API Key** | ||
| ```bash | ||
| export RECOUP_API_KEY=$(curl -s -X POST "https://recoup-api.vercel.app/api/agents/signup" \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{"email": "agent+'$(date +%s)-$RANDOM'@recoupable.com"}' | jq -r .api_key) | ||
| ``` | ||
|
|
||
| ### With email verification (for humans) | ||
|
|
||
| ```bash | ||
| # Step 1 — request a code | ||
| curl -X POST "https://recoup-api.vercel.app/api/agents/signup" \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{"email": "you@example.com"}' | ||
|
|
||
| # Step 2 — submit the code | ||
| curl -X POST "https://recoup-api.vercel.app/api/agents/verify" \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{"email": "you@example.com", "code": "123456"}' | ||
| ``` | ||
|
|
||
| ### From the dashboard | ||
|
|
||
| Go to [chat.recoupable.com/keys](https://chat.recoupable.com/keys), sign in, and create a key. | ||
|
|
||
| <Warning> | ||
| 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. | ||
| Keys are shown once. They are stored as HMAC-SHA256 hashes and cannot be retrieved after creation. | ||
| </Warning> | ||
|
|
||
| ### Using an API Key | ||
| --- | ||
|
|
||
| Pass your key in the `x-api-key` header: | ||
| ## Use a key | ||
|
|
||
| ```bash | ||
| curl -X GET "https://recoup-api.vercel.app/api/tasks" \ | ||
| curl "https://recoup-api.vercel.app/api/research?q=Drake" \ | ||
| -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. | ||
| ## Organization access | ||
|
|
||
| - **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 | ||
| If your account belongs to an organization, your key can access data for any account in that org by passing `account_id`: | ||
|
|
||
| <Info> | ||
| 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. | ||
| </Info> | ||
| - **No org** — key accesses its own data only | ||
| - **Org member** — key can pass `account_id` to access any member's data | ||
|
|
||
| --- | ||
|
|
||
| ## Access Tokens (Privy) | ||
| ## Bearer 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. | ||
| For frontend apps with [Privy](https://privy.io) authentication: | ||
|
|
||
| ```bash | ||
| curl -X GET "https://recoup-api.vercel.app/api/tasks" \ | ||
| curl "https://recoup-api.vercel.app/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. | ||
| The API validates the JWT against Privy, extracts the user's email, and resolves it to a Recoup account. | ||
|
|
||
| --- | ||
|
|
||
| ## 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: | ||
| ## Access control | ||
|
|
||
| ``` | ||
| 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 | ||
| Request includes account_id? | ||
| ├── Same as key owner → allowed | ||
| ├── Shares an organization → allowed | ||
| └── No shared org → 403 | ||
| ``` | ||
|
|
||
| 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. | ||
|
|
||
| <Note> | ||
| The Recoup internal admin organization has universal access to all accounts. | ||
| </Note> | ||
|
|
||
| ### 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 | ||
| ## Errors | ||
|
|
||
| | 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` | | ||
|
|
||
| --- | ||
| | `401` | Missing/invalid credentials, or both headers | | ||
| | `403` | Valid credentials, insufficient access | | ||
|
|
||
| ## Security Notes | ||
| ## Security | ||
|
|
||
| - 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.com/keys) | ||
| - Keys stored as HMAC-SHA256 hashes — never plaintext | ||
| - Rotate compromised keys at [chat.recoupable.com/keys](https://chat.recoupable.com/keys) | ||
| - Never commit keys to version control |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.