Browse documentation
Integrations

API reference

Adding contacts, sending transactional email and pushing products from your own systems.

The API lets your own systems add contacts, push products and send transactional email. Available on Starter and above.

Authentication

Create a key under Settings → Integrations → API keys. Keys belong to one brand, so the key you use decides which brand the data lands in. Send it as a bearer token:

Header
Authorization: Bearer YOUR_API_KEY

The header x-api-key is accepted as an alternative. Keys are shown once at creation and stored only as a hash, so a lost key must be replaced rather than recovered.

Add or update a contact

POST https://www.nectazo.com/v1/contacts
curl -X POST https://www.nectazo.com/v1/contacts \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "person@example.com",
    "firstName": "Jordan",
    "lastName": "Reyes",
    "source": "website-signup",
    "listId": "YOUR-LIST-UUID",
    "customFields": { "plan": "trial" }
  }'
FieldRequiredNotes
emailYesMatched against existing contacts in the brand — an existing address is updated, not duplicated.
firstName, lastNameNoUsed by {{first_name}} personalisation.
sourceNoFree text recording where the signup came from.
listIdNoAdds the contact to a list, which can trigger an automation.
subscribedNoSet false to add someone without subscribing them.
customFieldsNoAny keys and values you like. Merged into what the contact already has, so sending one key leaves the rest alone.
updateOnlyNoSet true to update an existing contact and never create one. An unknown address returns 200 with skipped, not an error.

Suppression is respected: an address that previously unsubscribed is not resubscribed by an API call.

Enrich many contacts at once

Sets custom fields on contacts you already have — up to 500 per request, in one round trip. For anything annotating an existing list this is the endpoint to use: doing the same job one address at a time turns a few milliseconds of work into a minute and a half of latency.

POST https://www.nectazo.com/v1/contacts/enrich
curl -X POST https://www.nectazo.com/v1/contacts/enrich   -H "Authorization: Bearer YOUR_API_KEY"   -H "Content-Type: application/json"   -d '{
    "contacts": [
      { "email": "ada@example.com", "customFields": { "plan": "annual" } },
      { "email": "grace@example.com", "customFields": { "plan": "monthly" } }
    ]
  }'

It answers with how many were updated and how many of the addresses are not contacts, with the first fifty of those named:

Response
{ "updated": 1, "notFound": 1, "notFoundEmails": ["grace@example.com"] }
  • Custom fields are merged, so sending one key leaves every other field on the contact alone.
  • It never creates anybody. An address that is not a contact is counted and named, not added — which also means it can never trigger an opt-in email.
  • It cannot change a subscription status, add anyone to a list, or unsubscribe anyone. Use the single-contact endpoint for those.
  • A duplicated address within one request is applied once, and the last one wins.

Send a transactional email

POST https://www.nectazo.com/v1/transactional
curl -X POST https://www.nectazo.com/v1/transactional \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "person@example.com",
    "type": "password_reset",
    "subject": "Reset your password",
    "html": "<p>Click <a href=\"https://example.com/reset\">here</a> to reset.</p>"
  }'

type is your own label — it groups messages on the Transactional page, so keep it consistent.

Push products

POST /v1/products accepts batches of products and is what the WordPress plugin uses. Unless you are building your own integration, use the plugin instead.

List your forms

GET /v1/forms returns the published forms in the key's brand — enough to name one and to know how it opens. Drafts are left out, since a draft renders nothing.

GET https://www.nectazo.com/v1/forms
curl https://www.nectazo.com/v1/forms   -H "Authorization: Bearer nk_live_..."

{
  "forms": [
    {
      "id": "9a8cddd7-...",
      "name": "Free guide popup",
      "type": "popup",
      "trigger": "click",
      "clickSelector": "[data-nectazo-open]"
    }
  ]
}

It exists so an integration can offer a list to choose from rather than a box to paste an id into — the WordPress plugin uses it for exactly that. trigger is included because a caller offering several forms at once needs to know which of them open on their own: two of those on one page is two things covering the screen.

Responses and errors

StatusMeaning
200Success.
401Missing, invalid or revoked API key.
402A plan limit was reached. The body names the limit and the tier that covers it.
422The request body failed validation. The body says which field.
500 / 502Something failed on our side. Safe to retry.

Keeping keys safe

  • Server-side only. A key in browser JavaScript is a public key.
  • One key per system, so you can revoke one without breaking the others.
  • Revoke immediately if a key is exposed — revocation takes effect at once.

Something unclear or wrong? Tell us and we'll fix it.

API reference — Nectazo