W
WGF Group

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/contactsList every contact.
POST/api/contactsCreate a contact.
PATCH/api/contacts/:idUpdate a contact (name, status, owner, …).
DELETE/api/contacts/:idRemove a contact.
GET/api/dealsList every deal.
POST/api/dealsOpen a new deal.
PATCH/api/deals/:idUpdate a deal (stage, value, …).
DELETE/api/deals/:idRemove a deal.
GET/api/activitiesList the latest logged activity.
POST/api/activitiesLog a touchpoint.
GET/api/import-logsRead 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.

FieldTypeRequiredNotes
namestringYesOrganization or person.
emailstringNoVerified address only. Lowercased on write.
companystringYesOrganization name.
statusenumYeslead · prospect · customer · churned — the client-sales lifecycle.
ownerstringYesWGF person responsible.
contact_typeenumYesclient · referral_partner · vendor · other.
partner_tierenumPartners onlytier_1 … tier_4.
partner_categoryenumPartners onlyeconomic_development · chamber · startup_support · accelerator · investor · lender · cpa_tax · law_firm · university · founder_network · other.
geographystringNoRegion served.
sourcestringYesWhere the record came from.
relationship_stageenumPartners onlynot_contacted · researched · contacted · replied · meeting_scheduled · active_partner · nurture · declined · inactive.
priority_scoreintegerNo1–5, where 5 is the highest priority.
referral_potentialenumNohigh · medium · low · unknown.
next_actionstringNoNext concrete step.
next_action_datedateNoYYYY-MM-DD. Drives the follow-up queue.
last_touch_datedateNoYYYY-MM-DD.
website_urlurlNoBlank is valid. A value must be a complete http:// or https:// URL — never guessed.
linkedin_urlurlNoColumn always present; blank is valid when the page is unverified. A value must be a complete http:// or https:// URL.
notesstringNoShort 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_partnersEvery referral partner record.
?view=tier_1_partnersTier 1 partners only.
?view=active_partnersPartners at relationship stage active_partner.
?view=follow_up_queuePartners in contacted, replied, meeting_scheduled, or nurture whose next_action_date is today or earlier.
?contact_type=referral_partner&partner_tier=tier_2Filter 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_due

General

notecallemailmeetingdeal
curl -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.