Getting Started
Integrate your platform with RCMS features to complete the REC-CAP assessments with clients, embed recovery care planning workflows, and sync outcomes data. This guide walks you through requesting an API key, using the sandbox, and making your first API call.
What you can build
RCMS offers two integration paths, designed to work together:
- Iframe embeds — drop RCMS recovery support UI (assessments, goals, progress, life domains) directly into your staff tools and client-facing app. Partners get continuous UI improvements without shipping updates on their side.
- JSON API — provisioning, sync, enrollment, and discharge endpoints for server-to-server operations. Stable DTO layer protects partners from internal schema changes.
Request an API key
During the beta program, API keys are provisioned manually. Email jessica@recoveryoutcomes.org with:
- Your organization or platform name
- Intended use case (integration type, expected volume)
- Requested scope: network, organization, or client
- Whether you want a sandbox environment first (strongly recommended)
Self-service key provisioning will open after the beta.
Key scopes at a glance
| Scope | Who gets this | What it can access |
|---|---|---|
| network | Partner contracted with a network (e.g. OneStep serving the MARR Network) | All orgs within that network. Can create new orgs. Sees cross-org analytics. |
| organization | Partner contracted with a single org | Locked to one organization. Cannot create other orgs or see cross-org data. |
| client | Peer-support apps acting on behalf of a client | Locked to one client's own data. Read-heavy, used mostly for client portal embeds. |
Network membership is implicit
A network-scoped key encodes which network it belongs to. Example: OneStep receives a key scoped to the MARR Network. Every org OneStep creates with that key is automatically attached to MARR. OneStep's code never passes a network_id.
If you work with multiple networks, you'll get one key per network — same code on your side, different environment variable.
Sandbox vs production
Every partner gets a dedicated sandbox Supabase project before touching production. Sandbox data is pre-seeded with fictional clients (Stark Industries) so you can immediately run through real scenarios without polluting real organizations.
| Environment | Base URL | Key format |
|---|---|---|
| Sandbox | https://api-sandbox.measurerecovery.com/v1 | rcms_test_... |
| Production | https://api.measurerecovery.com/v1 | rcms_live_... |
The key prefix tells you which environment you're hitting. Sandbox data is reset on request; production is permanent.
Authentication
Every request must include your API key in the Authorization header as a bearer token:
Authorization: Bearer rcms_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxKeys are scoped at provisioning time (network / organization / client) and carry a permission set (clients:read, assessments:write, etc.). Keep keys secret; never commit them to source control or expose them in client-side JavaScript.
Your first API call
Mint an embed token so you can render an RCMS iframe in your app. This is the most common first integration step.
curl -X POST https://api-sandbox.measurerecovery.com/v1/embed-tokens \
-H "Authorization: Bearer rcms_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"embed_type": "clients/260/assessments",
"staff_user_id": "partner-staff-abc123",
"ttl_seconds": 1800
}'Response:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"iframe_url": "https://embed.measurerecovery.com/clients/260/assessments?token=eyJ...",
"expires_at": "2026-04-18T17:30:00Z"
}Drop iframe_url into an <iframe>on your staff client-record page. RCMS validates the token, enforces RLS server-side, and renders the assessment view with the staff member's permissions.
Rate limits
Every response includes rate-limit headers so you can pace your requests:
X-RateLimit-Limit— requests allowed per minuteX-RateLimit-Remaining— requests left in the current windowX-RateLimit-Reset— Unix timestamp when the window resets
| Tier | Limit | Use case |
|---|---|---|
| Basic | 100 requests / min | Default tier for new partners |
| Standard | 500 requests / min | Active integrations with >100 clients |
| Premium | 2,000 requests / min | Network-scale deployments |
Exceeding your limit returns 429 Too Many Requests. Back off and retry after the window resets.
Error handling
Errors follow a consistent shape so you can handle them programmatically:
{
"error": {
"code": "invalid_scope",
"message": "This API key cannot access resources outside its scoped organization.",
"request_id": "req_01J8XR7K9M1N2P3Q4R5S6T7U8"
}
}| Status | Meaning |
|---|---|
| 400 | Request body failed validation |
| 401 | Missing, malformed, or expired API key |
| 403 | Key lacks the required permission or scope |
| 404 | Resource not found, or hidden by RLS |
| 429 | Rate limit exceeded |
| 5xx | Server error — retry with exponential backoff |
Always log the request_id when surfacing errors — it's the fastest way for us to help debug.
Next steps
API Reference
Every endpoint with request and response examples.
Iframe Embeds
The 10 embed routes and how to use embed tokens.
Coming next