Developers

The Tarmac API

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.

Authentication

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"
PlanAPI access
FreeNone
BasicRead: every GET endpoint
ProFull: read and write
EnterpriseFull, 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.

Lead intake (public, no key)

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.

REST · /api/v2

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.

Lead ingest · send us any row

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/leadsOne 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.

Contacts

GET/contactsList contacts
GET/contacts/:idOne contact
POST/contactsCreate: firstName, lastName, email, phones: [{number, type, ok_to_call}], accountId, title, notes
PATCH/contacts/:idPartial update
DELETE/contacts/:idDelete

Accounts

GET/accountsList accounts
POST/accountsCreate: name, domain, industry, ownerUserId
PATCH/accounts/:idPartial update

Opportunities

GET/opportunitiesList opportunities
POST/opportunitiesCreate: contactId, stage, amountUsdMrr

Activities

GET/activitiesList activities (calls, notes, follow-ups)
POST/activitiesLog one: contactId, type, ts, payload

Errors

401Missing, malformed, or revoked key
403Plan doesn't include this access (read-only key writing, or no API access on the plan)
404No such record in this workspace
429Rate limit: honor Retry-After

Every error body is {"error": "a plain-English sentence"}.

Building something bigger? Webhooks, higher rate limits, and custom sync are Enterprise conversations; talk to sales. No SDK yet, on purpose: the API is small enough that fetch is the SDK. Tell us if you disagree.
Tarmac · built for salespeople, by salespeople Privacy · go-tarmac.com