Automation
Integrations & API
Let your team and the Zapia AI agent read and change the same live data the dashboard shows — over a simple, authenticated HTTP API.
API is live
The ZAPIA_API_KEY secret is configured. Automations that present it can now create and update contacts, deals, and activities.
Built for agents
Zapia (or any tool) drives the CRM through plain JSON requests.
Key-protected
Every call must carry the shared secret. No key, no access.
Always in sync
API changes and team edits share one database and feed the same charts.
Authentication
Send the key on every request using either header:
Authorization: Bearer YOUR_ZAPIA_API_KEY X-API-Key: YOUR_ZAPIA_API_KEY
Endpoints
| GET | /api/contacts | List every contact. |
| POST | /api/contacts | Create a contact. |
| PATCH | /api/contacts/:id | Update a contact (name, status, owner, …). |
| DELETE | /api/contacts/:id | Remove a contact. |
| GET | /api/deals | List every deal. |
| POST | /api/deals | Open a new deal. |
| PATCH | /api/deals/:id | Update a deal (stage, value, …). |
| DELETE | /api/deals/:id | Remove a deal. |
| GET | /api/activities | List the latest logged activity. |
| POST | /api/activities | Log a touchpoint. |
| GET | /api/import-logs | Read the CSV import history, including per-row errors. |
Example: add a lead
A request Zapia might send when it captures a new inbound lead:
curl -X POST "$SITE_URL/api/contacts" \
-H "Authorization: Bearer $ZAPIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Marion Delacroix",
"email": "marion@fabrikat.com",
"company": "Fabrikat",
"status": "lead",
"owner": "Dana Whitlock"
}'Valid contact statuses: lead · prospect · customer · churned. Valid deal stages: lead · qualified · proposal · negotiation · won · lost. A contact with no contact_type is stored as a client, so existing automations keep working unchanged.
Referral partner fields
Referral partners are stored as contacts with contact_type=referral_partner — never as deals. A partner only produces a deal once it refers a real prospect, which keeps pipeline totals and win rate undistorted. Every field below is accepted in snake_case (responses come back in camelCase). Enum values are lowercase, dates are YYYY-MM-DD, and unknown values stay blank rather than being filled with N/A or a guess.
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | Yes | Organization or person. |
email | string | No | Verified address only. Lowercased on write. |
company | string | Yes | Organization name. |
status | enum | Yes | lead · prospect · customer · churned — the client-sales lifecycle. |
owner | string | Yes | WGF person responsible. |
contact_type | enum | Yes | client · referral_partner · vendor · other. |
partner_tier | enum | Partners only | tier_1 … tier_4. |
partner_category | enum | Partners only | economic_development · chamber · startup_support · accelerator · investor · lender · cpa_tax · law_firm · university · founder_network · other. |
geography | string | No | Region served. |
source | string | Yes | Where the record came from. |
relationship_stage | enum | Partners only | not_contacted · researched · contacted · replied · meeting_scheduled · active_partner · nurture · declined · inactive. |
priority_score | integer | No | 1–5, where 5 is the highest priority. |
referral_potential | enum | No | high · medium · low · unknown. |
next_action | string | No | Next concrete step. |
next_action_date | date | No | YYYY-MM-DD. Drives the follow-up queue. |
last_touch_date | date | No | YYYY-MM-DD. |
website_url | url | No | Blank is valid. A value must be a complete http:// or https:// URL — never guessed. |
linkedin_url | url | No | Column always present; blank is valid when the page is unverified. A value must be a complete http:// or https:// URL. |
notes | string | No | Short factual context. No credentials or sensitive personal data. |
Example: add a referral partner
curl -X POST "$SITE_URL/api/contacts" \
-H "Authorization: Bearer $ZAPIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Arlington Chamber of Commerce",
"email": "",
"company": "Arlington Chamber of Commerce",
"status": "lead",
"owner": "William Green",
"contact_type": "referral_partner",
"partner_tier": "tier_1",
"partner_category": "chamber",
"geography": "Arlington, VA",
"source": "Referral Partner Target List",
"relationship_stage": "not_contacted",
"priority_score": 5,
"referral_potential": "high",
"next_action": "Identify membership director",
"next_action_date": "2026-08-12",
"last_touch_date": "",
"website_url": "",
"linkedin_url": "",
"notes": "Large member base of small businesses."
}'Saved views
Append any of these to GET /api/contacts. The same views are available as tabs on the Partners page.
?view=referral_partners | Every referral partner record. |
?view=tier_1_partners | Tier 1 partners only. |
?view=active_partners | Partners at relationship stage active_partner. |
?view=follow_up_queue | Partners in contacted, replied, meeting_scheduled, or nurture whose next_action_date is today or earlier. |
?contact_type=referral_partner&partner_tier=tier_2 | Filter directly on contact_type, partner_tier, relationship_stage, or status. |
Activity types
One primary contact record per person or organization; every interaction is an activity against it. Logging an activity with a contact_id also advances that contact's last_touch_date.
Referral relationship
researchemail_sentemail_receivedlinkedin_messageevent_attendedintroduction_requestedintroduction_receivedmeeting_scheduledmeeting_completedworkshop_discussedreferral_receivedfollow_up_dueGeneral
notecallemailmeetingdealcurl -X POST "$SITE_URL/api/activities" \
-H "Authorization: Bearer $ZAPIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contact_id": 12,
"type": "email_sent",
"subject": "Intro email sent to membership director",
"body": "Sent overview of WGF workshops for member businesses.",
"occurred_at": "2026-08-05T14:30:00Z",
"owner": "William Green"
}'CSV import format
Bulk partner lists are imported from the Partners page, which validates the header, checks every enum and date, lowercases emails, detects duplicates on normalized company + email, and shows a create/update/skip/flag preview that you must confirm before anything is written. Blank cells never overwrite a populated field, and each run is recorded in the import log. The header must match exactly:
name,email,company,status,owner,contact_type,partner_tier,partner_category,geography,source,relationship_stage,priority_score,referral_potential,next_action,next_action_date,last_touch_date,website_url,linkedin_url,notes
Security controls for live CRM data
- Verify site-level authentication remains active, keep credentials private, and do not share the dashboard URL publicly. The API remains separately key-protected.
- Keep the key in the site's environment variables only — never in browser code, HTML, or a repository. It is never returned by any endpoint.
- Imports, edits, and deletions are written to an audit log, and every import records its filename, counts, and errors.
- Partner records are not rendered on any public page, and no public page shows CRM totals.