Skip to main content
Docs/API Reference
v1 REST

Staffify Developer API

Build voice AI products on top of Staffify. Configure agents, manage phone numbers, handle calls in real-time, and query everything programmatically with a single REST API.

Base URL

https://api.staffifyai.com/v1

All requests require an API key in the Authorization header.

Quick start

1

Get an API key

Create a project at console.staffifyai.com and copy your project API key.

2

Create an agent with a server_url

Point the agent at your call handler endpoint. This is where Staffify sends tool calls during live calls.

3

Assign a phone number

Purchase and assign a number to the agent. Your agent is now live and taking calls.

Create your first agent

curl -X POST https://api.staffifyai.com/v1/agents \
  -H "Authorization: Bearer sfy_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Support Agent",
    "server_url": "https://your-server.com/call-handler",
    "language": "en-US",
    "voice": "Sarah",
    "recording": true
  }'

API key types

Project Keys

sfy_live_*
  • Scoped to one project
  • Used for all resource endpoints
  • Recommended for production apps

Org Keys

sfy_org_*
  • Manage multiple projects
  • Use X-Project-Id header to scope
  • Recommended for admin scripts / CI

Create keys at console.staffifyai.com under Project → API Keys.

Rate limits

TierRequests / minConcurrent calls
PAYG30010
Starter60050
Growth1,200100
EnterpriseUnlimitedUnlimited

Rate limit headers are returned on every authenticated response: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-RateLimit-Tier, X-Concurrent-Call-Limit. Enterprise accounts are not rate-limited; only X-RateLimit-Tier and X-Concurrent-Call-Limit are set (the limit and remaining headers are omitted).

Errors

All errors return JSON with a human-readable message and a machine-readable code.

{
  "error": "Rate limit exceeded",
  "code": "RATE_LIMIT_EXCEEDED",
  "retryAfter": 43
}
CodeHTTPMeaning
MISSING_API_KEY401No Authorization header or X-Api-Key header found
INVALID_API_KEY401Key not found, revoked, or malformed
INSUFFICIENT_CREDITS402Account paused due to zero credits
READ_ONLY_KEY403Write operation attempted with a read-only key
ORG_KEY_REQUIRED403Endpoint requires an org-level key
PROJECT_NOT_FOUND404X-Project-Id header points to unknown project
RATE_LIMIT_EXCEEDED429Per-minute request limit exceeded
AUTH_RATE_LIMITED429Too many failed authentication attempts from this IP

Pagination

All list endpoints use cursor-based pagination. Pass after=<cursor> and limit=N as query parameters. The response includes a next_cursor field that is null when there are no more pages.

Paginate through all agents

let cursor = null;
const allAgents = [];

do {
  const params = new URLSearchParams({ limit: '50' });
  if (cursor) params.set('after', cursor);

  const data = await fetch(
    `https://api.staffifyai.com/v1/agents?${params}`,
    { headers: { Authorization: `Bearer ${process.env.STAFFIFY_API_KEY}` } }
  ).then(r => r.json());

  allAgents.push(...data.agents);
  cursor = data.next_cursor;
} while (cursor !== null);

Resource ID prefixes

All resource IDs use a consistent prefix so you can identify the type at a glance. These are used in after cursors and filter parameters.

PrefixResource
agent_*Agents
call_*Calls
kb_*Knowledge bases
proj_*Projects

Health check

Verify your key works and discover its project and org scope. project_id is the numeric internal ID; org_id is the numeric org ID.

curl https://api.staffifyai.com/v1/health \
  -H "Authorization: Bearer sfy_live_YOUR_KEY"

# Response
{ "status": "ok", "tier": "payg", "project_id": 1, "org_id": 1 }
Staffify AI | API