Developers

API documentation

A versioned REST API over the same data the interface uses. Token-authed, scoped per token, and bound to one account.

Last updated August 20, 2026

In one minute

Base URL https://getfullarc.com/api/v1. Authenticate with Authorization: Bearer <token>. Call GET /me to confirm which account a token belongs to. Subscribe to changes with webhooks rather than polling. Connecting a website? Start with Connect your website.

Getting started

The API is REST over HTTPS, returns JSON, and is versioned in the path. Everything lives under:

https://getfullarc.com/api/v1

Tokens are created in your account, and the full value is shown once. Connecting a website? Settings → Integrations → Your website creates the two tokens a site needs — see Connect your website. Sending email from your own app? Settings → Email Sending → Email API, once it is enabled for your account. For any other scope, write to support@getfullarc.com. Each screen issues a fixed set of scopes on purpose, so no settings page can mint a token broader than its job. Then confirm the token points where you think it does:

curl https://getfullarc.com/api/v1/me \
  -H "Authorization: Bearer fa_your_token_here"
{
  "success": true,
  "tenantId": "clx...",
  "tenantSlug": "your-company",
  "scopes": ["businesses:read", "leads:write"]
}

Do this first in any integration. A token is bound to exactly one tenant, and pushing records with the wrong one puts your data in someone else's account — /me is how you find out before that happens rather than after.

Authentication and scopes

Send the token as a bearer credential on every request. There are no API keys in query strings — a credential in a URL ends up in server logs, browser history and referrer headers.

Authorization: Bearer fa_your_token_here

Every token carries an explicit set of scopes, and a request outside them gets 403 rather than partial results. Grant the narrowest set that does the job: a token that can only read businesses cannot be turned into one that sends email.

ScopeGrants
businesses:readRead businesses and their contacts
businesses:writeCreate and update businesses
leads:writeCreate leads (contact + deal)
contacts:writeUpsert contacts, tags and custom fields
subscribers:writeAdd newsletter signups to your lists, with their consent
newsletters:writeLeave newsletter drafts for you to review and send — never sends
emails:sendSend transactional email
workflows:triggerEnrol contacts into drip campaigns
webhooks:manageList, create, change and delete webhook subscriptions — issued on request, for a server-held token only

Treat a token like a password. If one leaks, revoke it on the screen that created it — revoking takes effect immediately, and rotating is always cheaper than working out what was done with it. For a token we issued for you, write to support and we will revoke it.

Endpoints

Identity

Confirm what a token is before you trust it with anything.

EndpointWhat it doesScope
GET /meReturns the tenant a token belongs to and the scopes it carries.—

Businesses

The company records your pipeline hangs off.

EndpointWhat it doesScope
GET /businessesPaginated list. Filter by search text, session, rating, or whether a phone, email or website is present.businesses:read
POST /businessesCreate or merge a business.businesses:write
GET /businesses/{id}Full detail including contacts and enrichment history. Accepts an internal id or a Google Place ID.businesses:read
PATCH /businesses/{id}Update fields on one business.businesses:write

Intake

Getting people and opportunities into the CRM from your own site or app.

EndpointWhat it doesScope
POST /leadsCreates a contact and an early-stage deal, de-duplicating on email and phone.leads:write
POST /contactsUpsert a contact by email or phone, with tags and custom fields. No deal is created.contacts:write
POST /subscribersPut a newsletter signup on one of your lists, by list name, with the exact consent wording they ticked. Never re-subscribes someone who unsubscribed.subscribers:write
POST /newslettersLeave a newsletter DRAFT for you to review and send, built from email-builder blocks and addressed to your lists by name. Same name again refreshes the draft; it never sends.newsletters:write

Messaging

Send from your own systems through the same engine the product uses.

EndpointWhat it doesScope
POST /emailsSend one transactional email, with optional attachments. Suppression and unsubscribe handling still apply.emails:send
POST /workflows/{workflowId}/triggerEnrol a contact into an active drip campaign. Trigger data becomes template variables.workflows:trigger

Sessions

Prospecting runs, if you use FullArc to find businesses.

EndpointWhat it doesScope
GET /sessionsSearch sessions, newest first, filterable by status and result count.—

Webhooks

Manage your subscriptions programmatically — see the webhooks page for payloads. The scope is issued on request, to a token kept on a server.

EndpointWhat it doesScope
GET /webhooksList subscriptions. Secrets are masked.webhooks:manage
POST /webhooksCreate a subscription. The signing secret is returned once and never again.webhooks:manage
PATCH /webhooks?id=Update a subscription — change its URL, events, or enabled state.webhooks:manage
DELETE /webhooks?id=Delete a subscription.webhooks:manage

A worked example

Sending a lead from your own website's contact form:

curl -X POST https://getfullarc.com/api/v1/leads \
  -H "Authorization: Bearer fa_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{
    "source": "website contact form",
    "contact": {
      "name": "Dana Whitfield",
      "email": "dana@example.com",
      "phone": "+1 555 0134",
      "companyName": "Whitfield Logistics"
    },
    "message": "Looking for a quote on fleet servicing."
  }'
{
  "success": true,
  "contactId": "clx...",
  "dealId": "clx...",
  "deduped": false
}

deduped: true means the email or phone matched somebody already in the CRM and the lead was attached to them instead of creating a second record. Post the same form twice and you get one contact, not two — so you do not need to build that check yourself.

Errors

Failures return a consistent shape, so you can handle them without parsing prose. Match on code; error is for people and its wording may change:

{ "success": false, "error": "Insufficient scope — leads:write required", "code": "insufficient_scope" }

Authentication refusals use these codes: unauthenticated and invalid_token (401), rate_limited (429), insufficient_scope and origin_not_allowed (403), no_tenant (422).

StatusMeansWhat to do
400The request body failed validationRead error — it names the field. Do not retry unchanged.
401Token missing, malformed, or deletedCheck the header. Retrying will not help.
403The token lacks the scope for this endpointAsk support to add the scope. Scopes are read on every request, so the same token works once it is added.
404No such record in this tenantOften a tenant mismatch rather than a missing record. Check /me.
429Rate limitedBack off and retry — see below.
5xxOur problemRetry with exponential backoff. Persisting? Tell us.

A 404 from a cross-tenant lookup is deliberate. Distinguishing “does not exist” from “exists but is not yours” would confirm the existence of another account's records to anyone holding a token.

Rate limits

Requests are rate limited per client. Every response carries the current state, so you can pace yourself rather than discovering the ceiling by hitting it:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87

On a 429, back off exponentially rather than retrying immediately. For bulk work, prefer one paginated request over many single-record ones — limit on /businesses goes up to 1000.

OpenAPI document

The machine-readable spec is public and needs no token. Point Swagger UI, Redoc, Postman or a client generator straight at it:

curl https://getfullarc.com/api/v1/openapi

It is OpenAPI 3.1, and a test compares its paths against the deployed route files — so if it lists an endpoint, that endpoint exists, and if an endpoint exists, it is listed.

Getting help

Something undocumented, unclear, or behaving differently from this page? Write to support@getfullarc.com with the request you sent and what came back. Discrepancies between this page and the API are treated as defects in whichever one is wrong.