Push leads in. Sync contacts, accounts, opportunities, and activities out. Plain JSON over HTTPS, Bearer keys, no SDK required; if your tool can make an HTTP request, it can talk to Tarmac.
Create an API key in Settings → Workspace → API keys (workspace admins only). The secret is shown once at creation. Send it on every request:
curl https://app.go-tarmac.com/api/v2/contacts \ -H "Authorization: Bearer tmk_live_your_key_here"
| Plan | API access |
|---|---|
| Free | None |
| Basic | Read: every GET endpoint |
| Pro | Full: read and write |
| Enterprise | Full, plus higher limits and webhooks by arrangement |
Rate limit: 120 requests/minute per key (429 with a Retry-After header past it). Revoke keys any time from Settings; revocation is immediate.
Every workspace gets an intake URL with a private token; find yours under Contacts → +New lead → Share form. POST any form payload; common field aliases (first_name, fname, tel, email_address, …) are normalized automatically, and a fullName is split for you. Perfect for website forms, Zapier, or your ad platform's webhook.
curl -X POST https://app.go-tarmac.com/api/intake/<your-token> \
-H "Content-Type: application/json" \
-d '{
"firstName": "Maria",
"lastName": "Gonzalez",
"phone": "(818) 555-0142",
"email": "maria@example.com",
"company": "Gonzalez Roofing",
"notes": "Asked about weekly service"
}'
New leads route by your workspace rules (owner match → territory → round-robin) and appear in the dialer queue like any hand-entered lead. Do-not-call numbers are flagged before anyone dials.
Base URL https://app.go-tarmac.com/api/v2. Every route is scoped to the key's workspace; there is no cross-workspace access, ever.
POST /leads is the door for Clay, n8n, Zapier, Make and anything else that emits rows. Unlike POST /contacts it does not require our field names; send the row as-is and we map it: column aliases first, then the values themselves (an email is an email whatever the column is called). Columns we don't recognize are kept as custom fields, never dropped.
POST/leads | One row object, {"rows": [...]}, or a bare array. Max 100 rows per request. |
?source= | Tags provenance for lead-source reporting. Defaults to clay. |
People vs. companies. A row with a person in it (name, email, title, LinkedIn profile) becomes a contact and links to its account. A row with only company signals (name, industry, size, domain) becomes an account; we never invent a person named "Google" from a company list.
Re-sending is safe. Rows match existing records on email, phone, or LinkedIn and upsert: blanks get filled, and a human's edit is never overwritten by a vendor's guess. Run the same enrichment table daily without creating duplicates.
curl -X POST https://app.go-tarmac.com/api/v2/leads \
-H "Authorization: Bearer tmk_live_…" \
-H "Content-Type: application/json" \
-d '{"First Name":"Jane","Work Email":"jane@acme.com",
"Job Title":"VP RevOps","Company Name":"Acme Corp",
"Mobile Phone":"+1 415 555 0142","Funding Stage":"Series B"}'
{"ok":true,"received":1,"created":1,"updated":0,"skipped":0,
"results":[{"status":"created","contactId":"c_…","accountId":"a_…"}]}
Clay setup: in your table add HTTP API as an action → method POST → URL above → headers Authorization: Bearer <your key> and Content-Type: application/json → body: map your columns into a flat JSON object (or pass the whole row). Clay's HTTP API action requires their Growth plan or an active trial; on the free plan, export the table to CSV and use Import in the app instead, same mapping engine.
GET/contacts | List contacts |
GET/contacts/:id | One contact |
POST/contacts | Create: firstName, lastName, email, phones: [{number, type, ok_to_call}], accountId, title, notes |
PATCH/contacts/:id | Partial update |
DELETE/contacts/:id | Delete |
GET/accounts | List accounts |
POST/accounts | Create: name, domain, industry, ownerUserId |
PATCH/accounts/:id | Partial update |
GET/opportunities | List opportunities |
POST/opportunities | Create: contactId, stage, amountUsdMrr |
GET/activities | List activities (calls, notes, follow-ups) |
POST/activities | Log one: contactId, type, ts, payload |
401 | Missing, malformed, or revoked key |
403 | Plan doesn't include this access (read-only key writing, or no API access on the plan) |
404 | No such record in this workspace |
429 | Rate limit: honor Retry-After |
Every error body is {"error": "a plain-English sentence"}.
fetch is the SDK. Tell us if you disagree.