Build with our API.
One bearer token. ABN capabilities your account is approved to use - text employees, workflows, agents, MCP. The same credit balance powers the web app, your scripts, your agents, and your customers' calls into our API. Your app calls ABN services; ABN handles execution behind the service boundary.
Quickstart
Everything you can do in the web app you can do via the API. Same credits, same ABN employees and workflows, exposed as HTTPS endpoints under https://automatebusinessnow.com/api/v1. ABN handles execution internally; the API is service-native (e.g. image:generate), not model-native.
Use the key as an ABN app key
Your backend can use one abn_* key to power an entire application: employees, coding, images, video, voice, transcription, agents, jobs, credits, and short-lived client tokens. Call the ABN capability endpoint that matches the product action and send intent fields. ABN handles the underlying model/runtime work internally.
If a field is not documented for an ABN endpoint, do not send it. The standard app API does not accept modelId, provider, or vendorApiKey routing fields. If you are building browser or mobile flows, keep the root abn_* key on your backend and mint scoped abnct_* client tokens with /v1/tokens/mint.
// Do: call an ABN capability with intent fields.
POST /api/v1/images
Authorization: Bearer abn_YOUR_KEY_HERE
{
"prompt": "A pixel-art mushroom on cream paper",
"aspectRatio": "1:1",
"quality": "high",
"style": "illustration"
}
// Not part of the standard app API:
// modelId, provider, vendorApiKeyYour first call
The status endpoint is unauthenticated - paste it into your terminal to confirm the API is reachable from your machine.
curl https://automatebusinessnow.com/api/v1/statusYou should see something like:
{
"ok": true,
"service": "automatebusinessnow",
"version": "v1",
"timestamp": "2026-04-25T00:00:00.000Z"
}Now run a real job. Replace abn_YOUR_KEY_HERE with a key from your API keys page.
curl https://automatebusinessnow.com/api/v1/chat \
-H "Authorization: Bearer abn_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-H "X-Request-ID: req_your_trace_id_123" \
-d '{
"employeeSlug": "copywriter",
"prompt": "Visitor asks whether Detroit Auto Parts has brake pads in stock",
"latencyProfile": "website_chat",
"responseFormat": "plain_text",
"stream": true
}'Credits & billing
Every API call deducts from the same credit balance you see at /app/credits. Failed jobs auto-refund. Plan credits refresh monthly; top-up credits never expire.
Heads-up: when a single API key burns more than 100,000 credits in 60 seconds ($1,000/min sustained), the key is auto-revoked as a safety circuit. That ceiling sits well above any legitimate single-call cost, but it stops a runaway loop dead before it bleeds your balance. Generate a new key from /app/api-keys if it ever trips. For vetted high-volume accounts we lift the cap - email hello@automatebusinessnow.com.
Authentication
All /v1/* endpoints (except /v1/status) require a bearer token. You can have an unlimited number of keys per account, name them per integration, and revoke them individually.
Creating keys
Open /app/api-keys in the web app, give your key a name ("Zapier", "internal-script", etc.), and copy the resulting abn_... string. Keys are shown once at creation and never again - store them in your secret manager.
Sending the bearer
Authorization: Bearer abn_YOUR_KEY_HEREAnything else (no header, malformed prefix, revoked key) returns 401 { "ok": false, "error": "Unauthorized" }.
Async pattern - submit then poll
Every endpoint that runs a model accepts a synchronous call, but for production workloads the async submit-then-poll patternis cleaner: submit returns instantly with a job id, you poll a status endpoint until the result is ready - drop-in compatible with any poll-loop you've already written.
GET /v1/jobs/{id}
Single-shot poll. Non-blocking. Returns the current status; on completion finalizes the credit ledger atomically and returns the output URL. Subsequent polls of a completed job are idempotent - they re-read the cached terminal state, balance doesn't change.
curl https://automatebusinessnow.com/api/v1/jobs/abn_job_... \
-H "Authorization: Bearer abn_YOUR_KEY_HERE"While running:
{
"ok": true,
"jobId": "abn_job_...",
"status": "running",
"estimateCredits": 18,
"createdAt": "..."
}On completion:
{
"ok": true,
"jobId": "abn_job_...",
"status": "completed",
"outputUrl": "https://...png",
"creditsUsed": 18,
"balance": 18093,
"createdAt": "...",
"completedAt": "..."
}On failure (credits auto-refunded):
{
"ok": false,
"jobId": "abn_job_...",
"status": "failed",
"error": "human-readable sentence",
"creditsUsed": 0,
"createdAt": "..."
}Polling cadence: 4"8 seconds is plenty. Most image jobs land in 30"60s; longer agent runs vary by workflow.
Capability endpoints (/v1/images, /v1/voice/synthesize, /v1/voice/transcribe, /v1/agents/{id}/invoke) already return a job id when the underlying work is async - poll with the same GET /v1/jobs/{id} handler above. That covers every customer-facing integration.
Endpoints
Every endpoint accepts and returns application/json. Responses are always shaped { ok, ... } on success and { ok: false, error } on failure. Customer-debuggable responses include requestId and latencyMs; send X-Request-ID if you want ABN to echo your own trace id.
/v1/employeesList the valid text-employee slugs accepted by /v1/chat, plus required scope and whether your key can access each one.
(no body){
"ok": true,
"employees": [
{
"slug": "copywriter",
"name": "Copywriter",
"scopeRequired": "employee:copywriter",
"accessible": true,
"responseFormats": ["markdown", "plain_text"]
}
]
}/v1/chatRun a text-employee job. Use latencyProfile=website_chat for customer-facing website chat widgets.
{
"employeeSlug": "copywriter",
"prompt": "Visitor asks whether Detroit Auto Parts has brake pads in stock",
"imageUrl": null,
"fileContext": null,
"latencyProfile": "website_chat",
"responseFormat": "plain_text",
"stream": true
}# stream=false response
{
"ok": true,
"employeeSlug": "copywriter",
"kind": "text",
"message": "1. \"Your inbox is leaking leads...\"\n2. ...",
"imageUrl": null,
"executionClass": "ai",
"latencyProfile": "website_chat",
"responseFormat": "plain_text",
"requestId": "req_your_trace_id_123",
"latencyMs": 1800,
"creditsUsed": 1,
"balance": 18119
}
# stream=true response
Content-Type: text/event-stream
event: start
data: {"ok":true,"employeeSlug":"copywriter","latencyProfile":"website_chat","requestId":"req_..."}
event: text
data: {"delta":"Your inbox is leaking leads...","requestId":"req_..."}
event: done
data: {"ok":true,"creditsUsed":1,"balance":18119,"requestId":"req_..."}Streaming: set stream to true or send Accept: text/event-stream. The stream emits start, text, optional stage/image, terminal done, or terminal error. For website chat, set latencyProfile to website_chat, pair it with responseFormat plain_text, display a typing state, and log requestId for support.
/v1/imagesGenerate an image with the Graphic Designer employee.
{
"prompt": "Minimalist logo for a coffee shop named Hearth",
"aspectRatio": "1:1",
"quality": "high",
"style": "brand mark"
}{
"ok": true,
"outputUrl": "https://...png",
"creditsUsed": 8,
"balance": 18111
}/v1/voice/synthesizeVoice-agent-grade TTS — streams audio bytes back for live voice agents.
{
"text": "Hi, thanks for calling. How can I help you today?",
"voice": "warm-female",
"format": "mp3",
"model": "fast"
}Streamed audio bytes (Content-Type: audio/mpeg or audio/L16).
Headers: X-Credits-Used, X-Voice-Format.
Catalog voices: warm-female, deep-male, energetic-female,
british-male, young-female, podcast-host.
Formats: mp3 (default) | pcm_16000 (telephony pipelines).
Models: fast (~300ms TTFB) | quality (better prosody, slower).
Billing: 1 credit per 50 chars on fast,
1 credit per 25 chars on quality./v1/voice/transcribeSpeech-to-text with word-level timestamps. multipart/form-data with an `audio` field. Up to 25 MB / 1 hour.
# multipart/form-data
audio: <binary mp3/wav/m4a/ogg/webm>
language: en # optional - auto-detect if omitted
diarize: true # optional - speaker labels per word{
"ok": true,
"text": "the full transcript here",
"words": [
{ "word": "the", "start": 0.12, "end": 0.18 },
{ "word": "full", "start": 0.18, "end": 0.42 }
],
"languageCode": "en",
"durationSeconds": 12.4,
"creditsUsed": 7
}
Billing: 1 credit per 2 seconds of audio (~$18/hr retail).Use automatebusinessnow as the voice for your AI voice agent.
Use your abn_live_* key for TTS + STT in your voice agent. Single bearer token, single credit balance, agent-friendly streaming, and stable ABN catalog voices.
1. Synthesis (TTS)
POST https://automatebusinessnow.com/api/v1/voice/synthesize
Headers: Authorization: Bearer abn_live_xxx
Body: { text, voice: "warm-female", format: "mp3", model: "fast" }
Pass a catalog key (warm-female, deep-male, energetic-female, british-male, young-female, podcast-host). The response stream is byte-identical audio/mpeg or audio/L16 (PCM 16kHz). No buffering on our end; we add ~5"15ms of overhead.
2. Transcription (STT)
POST https://automatebusinessnow.com/api/v1/voice/transcribe Headers: Authorization: Bearer abn_live_xxx Form: audio=<bytes> # field name is "audio", not "file"
Response keys are camelCase + wrapped in { ok: true, ... }: audio_duration -> durationSeconds, language_code -> languageCode.
3. Auth + billing
- - Generate an
abn_live_*key at /app/api-keys. One key for both endpoints. - - Keep a credit balance - TTS bills per character, STT bills per second. Credits never expire when bought as top-ups; failed jobs auto-refund.
- - Per-key burn detection auto-revokes the key if a runaway loop drains credits unusually fast. Other keys stay live.
- - Rate limit: 60 TTS calls/min, 20 STT calls/min by default per key. Tier upgrades scale these.
- - Hardcoded voice settings (stability, similarity_boost, style) on synth. Custom per-call settings + WebSocket input-streaming are not exposed in v1 - open an issue if you need them.
/v1/agents/{id}/invokeInvoke a configured autonomous agent on demand. The agent runs with its memory + connections, may queue work.
{
"input": "Process new leads in HubSpot from today"
}{
"ok": true,
"runId": "run_3a8b...",
"status": "queued"
}/v1/creditsCurrent credit balance for the key's owner.
(no body){
"ok": true,
"balance": 18121
}/v1/statusPublic health check. No auth required.
(no body){
"ok": true,
"service": "automatebusinessnow",
"version": "v1",
"timestamp": "2026-04-25T00:00:00.000Z"
}Rate limits
Every endpoint has a per-key rate limit. The cap scales with your plan tier - Power users get 10x the Free baseline. When you exceed it, the response is 429 Rate limit exceeded and your credits are not charged.
| Endpoint | Free / Starter | Pro / Scale | Power |
|---|---|---|---|
| /v1/chat | 30 / 60 | 120 / 180 | 300 rpm |
| /v1/images | 10 / 20 | 40 / 60 | 100 rpm |
| /v1/voice/synthesize | 20 / 40 | 80 / 120 | 200 rpm |
| /v1/voice/transcribe | 10 / 20 | 40 / 60 | 100 rpm |
| /v1/agents/* | 5 / 10 | 20 / 30 | 60 rpm |
Errors
Every error response is JSON-shaped. The HTTP status tells you the category; the error field is a stable machine code (e.g. scope_required) that your handler can switch on; the hint field is a human-readable sentence safe to surface in your UI; some errors include extra fields (e.g. scope, requiredScope, capCredits) you can use to render a tailored error or upsell.
{
"ok": false,
"error": "scope_required",
"code": "scope_required",
"message": "This key does not hold image:generate.",
"requestId": "req_01HX...",
"latencyMs": 14,
"scope": "image:generate",
"hint": "Your key isn't approved for image generation yet.",
"upgradeUrl": "/app/api-keys"
}HTTP status reference
| Status | Meaning | What to do |
|---|---|---|
| 400 | Invalid request body / bad input | Check the JSON shape and required fields |
| 401 | Missing / bad / revoked key, or token expired | Generate a new key or mint a fresh client token |
| 402 | Insufficient credits | Top up at /app/credits - credits never expire |
| 403 | Key lacks required scope or org gate | See error code below; some are unlockable via /app/billing |
| 404 | Unknown employee / capability / job | Check the slug or id against the docs above |
| 429 | Rate limit exceeded or per-key cap hit | Backoff and retry, or raise the cap on /app/api-keys |
| 500 | Upstream model failed | Credits auto-refunded; safe to retry |
| 503 | Cap-check infra unavailable | Retry after Retry-After header (5-10s) |
Error code reference
Use the error string to branch your handler - HTTP statuses collapse several distinct conditions into a single number.
scope_requiredHTTP 403Your key isn't approved for this capability.
{
"ok": false,
"error": "scope_required",
"scope": "image:generate",
"upgradeUrl": "/app/api-keys"
}If `scope` is `image:generate`, `video:generate`, `audio:generate`, `voice:synthesize`, `voice:transcribe`, or `image:upscale`, complete verified-org promotion at /app/billing. For any other scope, recheck your key's scope list on /app/api-keys or contact hello@automatebusinessnow.com.
verified_org_requiredHTTP 403Workflow scope needs verified-org promotion before it can be exercised.
{
"ok": false,
"error": "verified_org_required",
"hint": "Add a payment method or verify your domain to enable this capability.",
"verifyUrl": "/app/billing#verify-org"
}Add a payment method at /app/billing, verify a domain via DNS-TXT, or request manual account verification from /app/billing#verify-org.
end_user_id_requiredHTTP 400Partner keys above ~100 req/day must attribute each call to a stable end-user id.
{
"ok": false,
"error": "end_user_id_required",
"hint": "Send X-ABN-End-User-ID: <stable opaque id> on every call."
}Hash a stable per-end-user identifier and send it in the X-ABN-End-User-ID header. PII is never required.
end_user_id_invalidHTTP 400The X-ABN-End-User-ID header is present but malformed (e.g. > 128 chars, control chars).
{
"ok": false,
"error": "end_user_id_invalid",
"hint": "End-user ids must be 1"128 printable ASCII characters."
}Hash to a fixed length (we recommend the first 32 hex chars of sha256(your-id)).
origin_not_allowedHTTP 403A client token (abnct_*) was used from an Origin that isn't in its allowed_origins list.
{
"ok": false,
"error": "origin_not_allowed",
"hint": "This token cannot be called from the requesting origin."
}Mint a fresh token from your backend with the right Origin in `allowed_origins`, or call from the registered origin.
capability_unavailableHTTP 403That ABN capability is not currently enabled for this key or account.
{
"ok": false,
"error": "capability_unavailable",
"capability": "image:generate",
"hint": "This capability isn't available on your key right now."
}Use the enabled ABN capabilities on your key, or contact hello@automatebusinessnow.com if you expected this service to be active.
capability_temporarily_unavailableHTTP 503ABN can route this capability for session callers in the live web app, but partner API keys are paused while ABN finalizes the underlying service agreement. Retry after ABN ships the agreement, or contact hello@automatebusinessnow.com for early-access updates.
{
"ok": false,
"error": "capability_temporarily_unavailable",
"capability": "video:generate",
"hint": "This capability is in limited release on partner API keys while ABN finalizes the underlying service agreement."
}Honor the `Retry-After` header and retry, or reach out for early-access scheduling.
key_daily_cap_exceededHTTP 429Today's spend on this key has crossed its `daily_credit_cap`.
{
"ok": false,
"error": "key_daily_cap_exceeded",
"capCredits": 5000,
"spentToday": 5020,
"estimate": 8
}Raise the cap on the key at /app/api-keys, or wait until the daily window rolls over (UTC midnight).
key_monthly_cap_exceededHTTP 429This calendar month's spend on this key has crossed its `monthly_credit_cap`.
{
"ok": false,
"error": "key_monthly_cap_exceeded",
"capCredits": 50000,
"spentMonth": 50020,
"estimate": 8
}Raise the cap on the key at /app/api-keys, or wait until the calendar month rolls over.
cap_check_failedHTTP 503The atomic cap-check RPC was momentarily unavailable. No credits were debited.
{
"ok": false,
"error": "cap_check_failed",
"hint": "Retry after a few seconds."
}Honor the Retry-After header (usually 5-10s) and retry. Safe - no spend occurred.
unauthorizedHTTP 401No bearer key, bad bearer key, revoked key, expired key, or expired client token.
{
"ok": false,
"error": "unauthorized",
"hint": "Send Authorization: Bearer abn_... or a valid abnct_... token."
}Mint a new key at /app/api-keys or a fresh client token via /v1/tokens/mint.
unknown_employeeHTTP 404The employeeSlug is not a valid public chat employee.
{
"ok": false,
"error": "unknown_employee",
"code": "unknown_employee",
"message": "Unknown employee slug: parts-agent. Call /api/v1/employees to list valid slugs.",
"employeeSlug": "parts-agent",
"requestId": "req_01HX...",
"latencyMs": 3
}Call GET /api/v1/employees and use one of the returned slugs, or build your own routing layer on top of an existing employee like customer-service.
invalid_response_formatHTTP 400responseFormat was not markdown or plain_text.
{
"ok": false,
"error": "invalid_response_format",
"code": "invalid_response_format",
"message": "responseFormat must be markdown or plain_text.",
"requestId": "req_01HX...",
"latencyMs": 2
}Use responseFormat="plain_text" for customer-facing chat widgets, or omit it for markdown.
invalid_latency_profileHTTP 400latencyProfile was not standard or website_chat.
{
"ok": false,
"error": "invalid_latency_profile",
"code": "invalid_latency_profile",
"message": "latencyProfile must be standard or website_chat.",
"requestId": "req_01HX...",
"latencyMs": 2
}Use latencyProfile="website_chat" for live widgets, or omit it for the standard employee workflow.
unsupported_routing_fieldHTTP 400A service endpoint received a routing field it does not accept. ABN service endpoints accept documented intent fields only.
{
"ok": false,
"error": "unsupported_routing_field",
"fields": ["modelId"],
"hint": "ABN service endpoints accept intent fields only."
}Drop modelId/provider/vendorApiKey fields and pass only the fields documented for the ABN endpoint.
SDKs & MCP
We don't ship a vendor SDK - every endpoint is plain HTTPS JSON, so any HTTP library works. We do publish two integration surfaces for AI tools:
- OpenAPI 3.1 spec at /api/v1/openapi- feed it to ChatGPT custom GPTs, Postman, or any tool-calling agent.
- MCP server config for Claude Desktop, Cursor, and other MCP-aware clients. Drop the snippet into your
mcp.jsonand your AI assistant can call us directly. See /developers for the full config.