Documentation Sign in
On this page

API v1

API documentation

With the DIGO Email API, your website, online shop or business system works together with your account: it subscribes contacts with their consent, sends products and posts to use in your emails, and records orders and carts so you can measure what each campaign sells and start automations.

Before you start

In these cases you don’t need to write any code, because the connection is ready-made:

  • WordPress and WooCommerce: download the plugin from Integrations. It brings into DIGO Email the sign-ups from checkout and from Contact Form 7 forms, plus orders, products, blog posts and carts.
  • digo.sale: in your shop’s admin open Marketing → DIGO Email and paste the key.
  • A sign-up form: every list has its own, to share with a link or embed in your site, in Lists and forms.
  • ChatGPT and Claude: connect your assistant from Integrations › ChatGPT and Claude. It signs in with your consent (OAuth), without the API key.

The API is for everything else: a custom-built website, another e-commerce platform, a CRM, a business system or an app with its own server.

Your account must be active. New accounts are reviewed, usually within one business day: in the meantime you can already connect your site and send products, but sign-ups are refused with 403 account_inactive.

Getting started

  1. In the dashboard open Integrations. Under Connect a site enter the site’s name and address and choose Website as the platform.
  2. Press Connect and create key and copy the key that appears: it starts with dge_ and we show it only once.
  3. Test the key by asking for the connection details:

Request

curl https://www.digo.email/api/v1/ping \
  -H "Authorization: Bearer dge_YOUR_KEY" \
  -H "Accept: application/json"

Response · 200

{
  "store": "Online shop",
  "account": "Rossi Ltd",
  "platform": "site",
  "can_send": true,
  "status": "active"
}

From the first successful request, the site shows as Connected in the dashboard.

Authentication

Every request carries the site’s key in the Authorization header, after the word Bearer:

Header

Authorization: Bearer dge_YOUR_KEY
  • One key per site. You can connect up to 20 sites, each with its own key. Products, posts, orders and carts belong to the site that sent them; contacts, lists, tags and fields belong to the account and apply to every site.
  • Keep it on your server. Anyone with the key can subscribe addresses and send orders in your name: never put it in your pages’ JavaScript, in an app installed on phones or in a public repository.
  • You see it only once. We store only an encrypted fingerprint of the key, and the dashboard shows its last six characters. If you lose it, create a new one.
  • To replace it open Integrations, then Edit or replace key › New key: the previous key stops working immediately. Do this if you think someone has seen it.
  • Disconnecting the site disables the key and deletes the products, posts and orders received from that site. Contacts stay.

Requests and responses

Every address starts like this:

https://www.digo.email/api/v1

  • JSON. Send data as JSON with Content-Type: application/json and ask for responses with Accept: application/json. Responses are always JSON, in UTF-8. Always use HTTPS.
  • Your own identifiers. Products, posts, orders and carts are recognised by your id (text, up to 64 characters). Sending the same id again updates the item instead of creating another one.
  • Amounts in units of the currency, with a dot for decimals: 49.90, not 4990. The currency is a three-letter code (EUR, GBP, USD); if it’s missing, the site’s currency set in Integrations applies.
  • Dates in ISO 8601 format with the time zone: 2026-10-20T09:30:00+02:00.
  • Messages. The message field of errors is written for people, in Italian, English, Spanish, French or German depending on the Accept-Language header or the account’s language. In your code, decide based on the HTTP status and the error field, which never change.
  • New fields. Fields may be added to responses: ignore the ones you don’t know.

Errors

2xx codes mean the request succeeded. Otherwise the response body explains what happened:

Response · 403

{
  "error": "account_inactive",
  "message": "The DIGO Email account isn’t active yet."
}
StatuserrorWhat it means and what to do
401invalid_keyMissing, wrong or replaced key. Check the key or create a new one.
403account_inactiveThe account is still under review and doesn’t accept sign-ups. We’ll email you when it’s active.
403account_suspendedSending from the account is suspended and sign-ups are refused. Contact support.
409contact_limitContacts have reached twice the account’s limit: new sign-ups are refused until you buy more contacts or remove the ones you don’t use.
409privacy_missingOnly for GET /forms: the link to your privacy policy is missing. Add it in Settings › Business.
422unknown_listNone of the lists given exists. Fetch the ids again with GET /lists.
422—Invalid data: the errors field lists the problems field by field. Fix the data before trying again.
429—Too many requests. Wait the number of seconds given in the Retry-After header.
5xx—A temporary problem on our side. Try again later, waiting a little longer each time.

Response · 422

{
  "message": "You must accept the consent statement.",
  "errors": {
    "consent": ["You must accept the consent statement."]
  }
}

Limits

  • Up to 300 requests a minute for each connected site, counting all endpoints.
  • For POST /contacts, at most 60 sign-ups a minute per site.
  • Products, posts and past orders travel in batches of 100 per request.
  • Responses show the general limit (X-RateLimit-Limit) and how many requests are left in the minute (X-RateLimit-Remaining). Beyond a limit you get 429 with Retry-After.

A request that failed with a network error, a 429 or a 5xx is safe to repeat: orders, products, posts and carts are updated by id, and a contact who is already subscribed isn’t duplicated. Other 4xx errors, instead, come back the same until you fix the data.

List of endpoints

MethodPathWhat it’s for
GET/pingChecks the key and the account’s status
GET/listsLists, with their ids
GET/tagsTags
GET/fieldsContacts’ custom fields
GET/formsSign-up forms, ready to display
POST/contactsSubscribes a contact with their consent
PUT/itemsCreates or updates products and posts
DELETE/items/{type}/{id}Removes a product or a post
POST/ordersRecords an order or updates its status
POST/orders/historyImports past orders
PUT/cartsSaves a customer’s cart
DELETE/carts/{id}Closes an emptied cart

Account and settings

These endpoints read what you’ve set up in the dashboard: your site uses them to let whoever configures it pick lists, tags and fields.

GET /ping

Checks the key and the account’s status. Call it when someone pastes the key into your site’s settings and, from time to time, to know whether the account accepts sign-ups. The response is the one shown in Getting started.

FieldTypeDescription
storestringThe site’s name in Integrations.
accountstringThe name of the DIGO Email account.
platformstringThe chosen platform: woocommerce, digo_sale or site (Website).
can_sendbooleantrue when the account is active and accepts sign-ups.
statusstringpending (under review), active or suspended (sending suspended).

GET /lists

The account’s lists in alphabetical order, with the id to use when subscribing contacts.

Response · 200

{
  "data": [
    { "id": 3, "name": "Customers", "double_opt_in": false },
    { "id": 5, "name": "Newsletter", "double_opt_in": true }
  ]
}

With double_opt_in set to true, people who sign up get an email to confirm: they become subscribed, and receive campaigns, only after confirming.

GET /tags

The account’s tags in alphabetical order. To give a contact a tag, its name is enough: tags that don’t exist are created.

Response · 200

{
  "data": [
    { "id": 9, "name": "London" },
    { "id": 7, "name": "VIP" }
  ]
}

GET /fields

The contacts’ custom fields, which you create in Contacts › Custom fields.

Response · 200

{
  "data": [
    { "key": "birthday", "label": "Birthday", "type": "date" },
    { "key": "company", "label": "Company", "type": "text" }
  ]
}
FieldTypeDescription
keystringThe name to use in fields of POST /contacts. It’s also the placeholder in emails: {{birthday}}.
labelstringThe name shown in the dashboard.
typestringtext, number or date.

GET /forms

The lists’ sign-up forms, with everything you need to display them in your site’s style. This is what the WordPress plugin’s shortcode uses.

ParameterTypeDescription
langstringOptional, in the address: the page’s language (it, en, es, fr or de). Labels and consent text come in that language, unless the list has its own.

Request

curl "https://www.digo.email/api/v1/forms?lang=en" \
  -H "Authorization: Bearer dge_YOUR_KEY" \
  -H "Accept: application/json"

Response · 200

{
  "data": [
    {
      "id": 5,
      "name": "Newsletter",
      "title": "Subscribe to our newsletter",
      "action": "https://www.digo.email/f/k3Jd9QmZ2xTb7LpV4nWc8RyA1sGe6HuF",
      "locale": "en",
      "consent_text": "I agree to receive email communications from Rossi Ltd. I can unsubscribe at any time.",
      "labels": { "email": "Email", "optional": "optional", "privacy": "Privacy policy", "submit": "Subscribe" },
      "privacy_url": "https://www.yoursite.com/privacy",
      "double_opt_in": true,
      "fields": [
        { "name": "first_name", "label": "First name", "type": "text", "required": false },
        { "name": "fields[birthday]", "label": "Birthday", "type": "date", "required": false }
      ],
      "script": "https://www.digo.email/js/digo-form.js?v=3",
      "can_send": true
    }
  ]
}

The form doesn’t go through your server: the visitor’s browser sends it straight to the action address, without a key. Consent, double opt-in and abuse protection are those of DIGO Email’s forms. To build it:

  • a <form method="post"> with action as its target;
  • the email field and the fields in fields, each with its name, required when required is true;
  • a consent checkbox next to the consent_text text and the link to privacy_url, plus a hidden consent_text field with the same text;
  • the script given in script. On the account’s own sites (verified sending domains and connected sites) it sends the form without leaving the page and shows the answer right there; elsewhere, or without the script, the visitor sees the answer on a DIGO Email page.

Don’t name any field website: it’s the trap for automated programs, and a form that fills it in is ignored. Without the link to the privacy policy in the account’s settings the response is 409 privacy_missing.

Contacts

POST /contacts

Subscribes a person who has agreed to receive your emails: from a form on your site, at checkout or when registering. Without consent nothing is saved.

FieldTypeDescription
emailrequiredstringThe email address, up to 190 characters.
list_idsrequiredarrayThe list ids, from 1 to 10 (GET /lists). Ids that don’t exist are ignored; if none exists the response is 422 unknown_list.
consentrequiredbooleanMust be true: the person ticked the consent checkbox.
consent_textrequiredstringThe exact text of the checkbox the person ticked, up to 1,000 characters. We keep it as proof of consent.
sourcerequiredstringWhere they signed up: form (a form), checkout (a purchase) or registration (creating an account on your site).
first_namestringFirst name, up to 100 characters.
last_namestringLast name, up to 100 characters.
fieldsobjectCustom fields, by key (GET /fields): {"birthday": "1990-04-18"}. Dates as YYYY-MM-DD, numbers as JSON numbers (12.5). Fields that don’t exist are ignored.
tagsarrayUp to 10 tag names, of 60 characters at most. Tags that don’t exist are created.
languagestringThe person’s language: it, en, es, fr or de (en_GB or English work too). Confirmation emails, campaigns and unsubscribe pages will follow it. A language we don’t support is ignored. It can also be called locale.
formstringThe form’s name, up to 190 characters: it appears in the contact’s history.
pagestringThe address of the page where they signed up. We keep only the domain and path, without anything after ? or #.
ipstringThe visitor’s IP address, not your server’s: it’s part of the proof of consent.
user_agentstringThe visitor’s browser, also for the proof of consent.

Request

curl -X POST https://www.digo.email/api/v1/contacts \
  -H "Authorization: Bearer dge_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "email": "emma.wilson@example.com",
    "first_name": "Emma",
    "last_name": "Wilson",
    "list_ids": [5],
    "tags": ["Website"],
    "fields": { "company": "Wilson Design", "birthday": "1990-04-18" },
    "consent": true,
    "consent_text": "I want to receive the Rossi Ltd newsletter with news and offers.",
    "source": "form",
    "form": "Footer",
    "language": "en",
    "page": "https://www.yoursite.com/contact",
    "ip": "203.0.113.24",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 15_6) AppleWebKit/605.1.15"
  }'

Response · 200

{ "status": "confirming" }
statusWhat it means
subscribedSubscribed. If they were already a contact, the lists and tags have been added.
confirmingThey must confirm from the email we sent them: one of the lists has double opt-in, or they unsubscribed in the past.
limitedSign-up saved, but this address has already received too many confirmation emails today: the link will arrive if they sign up again tomorrow.
cappedSign-up saved, but the account has already sent today’s 500 confirmation emails: ask the person to try again tomorrow.

People who are already your contacts

  • Lists and tags are added, never removed.
  • First and last name stay as they are; custom fields are filled in only when empty, and the language only if they don’t have one.
  • Someone already subscribed joins double opt-in lists straight away too, without confirming again.
  • Someone who unsubscribed must confirm from their own inbox, even for lists without double opt-in: nobody can subscribe them again on their behalf. We send nothing to addresses that bounced or reported emails as spam.

What happens next

  • As soon as the contact is subscribed, right away or when they confirm, the Subscribes to a list and Gets a tag automations start.
  • Above your account’s contact limit the sign-up is saved anyway, but campaigns and automations stop until you buy more contacts or remove some; at twice the limit new sign-ups are refused with 409 contact_limit.
  • In the contact’s page you’ll find the sign-up with the consent text, the site, the page and the form.

PHP, on the server that receives the form

<?php
// The key comes from an environment variable: don’t write it in the code.
$consentText = 'I want to receive the Rossi Ltd newsletter with news and offers.';

if (empty($_POST['consent'])) {
    exit('To subscribe, tick the consent box.');
}

$ch = curl_init('https://www.digo.email/api/v1/contacts');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 10,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('DIGO_EMAIL_KEY'),
        'Content-Type: application/json',
        'Accept: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'email' => trim($_POST['email'] ?? ''),
        'first_name' => trim($_POST['name'] ?? ''),
        'list_ids' => [5],
        'consent' => true,
        'consent_text' => $consentText, // the same text shown next to the checkbox
        'source' => 'form',
        'language' => 'en',
        'page' => 'https://www.yoursite.com/contact',
        'ip' => $_SERVER['REMOTE_ADDR'],
        'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
    ]),
]);
$body = json_decode((string) curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

$messages = [
    'subscribed' => 'Thank you, you’re subscribed.',
    'confirming' => 'Almost done: open the email we sent you and confirm.',
    'limited' => 'We can’t send you more confirmation emails today: please try again tomorrow.',
    'capped' => 'We can’t send you more confirmation emails today: please try again tomorrow.',
];
if ($code === 200) {
    echo $messages[$body['status']] ?? $messages['subscribed'];
} else {
    error_log('DIGO Email: ' . ($body['message'] ?? 'HTTP ' . $code));
    echo 'We couldn’t complete your sign-up. Please try again later.';
}

Node.js 18 or later, on the server

const response = await fetch('https://www.digo.email/api/v1/contacts', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.DIGO_EMAIL_KEY}`,
    'Content-Type': 'application/json',
    Accept: 'application/json',
  },
  body: JSON.stringify({
    email: 'emma.wilson@example.com',
    list_ids: [5],
    consent: true,
    consent_text: 'I want to receive the Rossi Ltd newsletter with news and offers.',
    source: 'checkout',
    language: 'en',
  }),
});
const data = await response.json();
if (!response.ok) throw new Error(data.message);
console.log(data.status); // subscribed, confirming, limited or capped

Products and posts

The products and blog posts you send here appear in the email editor, in the Products and Posts blocks: whoever writes a campaign picks them from a list, with title, image, price and link ready to go.

PUT /items

Creates or updates up to 100 items per request, recognised by type and id. Send all of them the first time, then whenever their title, price, image or availability changes.

FieldTypeDescription
itemsrequiredarrayThe items, up to 100.
items[].typerequiredstringproduct or post.
items[].idrequiredstringYour id for the item, up to 64 characters.
items[].titlestringThe name. Items without a name are skipped.
items[].urlstringThe page’s full address, with https://. Items without a valid address are skipped.
items[].imagestringThe image’s full address.
items[].excerptstringA short description, up to 2,000 characters. HTML is removed.
items[].pricenumberThe price, as the customer sees it.
items[].sale_pricenumberThe discounted price: in emails it becomes the price, with the regular one struck through.
items[].availablebooleanfalse if the product isn’t available. If missing, it’s true.
items[].published_atstringThe publication date: in the list, the most recent posts come first.

Request

curl -X PUT https://www.digo.email/api/v1/items \
  -H "Authorization: Bearer dge_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "items": [
      {
        "type": "product",
        "id": "1042",
        "title": "Glazed ceramic mug",
        "url": "https://www.yoursite.com/products/glazed-mug",
        "image": "https://www.yoursite.com/media/glazed-mug.jpg",
        "excerpt": "Handmade, 350 ml, dishwasher safe.",
        "price": 24.00,
        "sale_price": 19.90,
        "available": true
      },
      {
        "type": "post",
        "id": "87",
        "title": "How to choose the right mug",
        "url": "https://www.yoursite.com/blog/right-mug",
        "image": "https://www.yoursite.com/media/blog-mugs.jpg",
        "excerpt": "Materials, size and care: a five-minute guide.",
        "published_at": "2026-10-12T08:00:00+02:00"
      }
    ]
  }'

Response · 200

{ "saved": 2, "skipped": [] }

saved counts the items saved; skipped lists the ids skipped because they had no name or no valid address.

In emails, products and posts are copied at the moment you pick them. If a price changes later, pick the product again in campaigns you’ve already prepared to update it.

DELETE /items/{type}/{id}

Removes from the list a product you no longer sell or a post that’s no longer published. It answers 204, with no content, even if the item wasn’t there. Emails already prepared that contain it don’t change.

Request

curl -X DELETE https://www.digo.email/api/v1/items/product/1042 \
  -H "Authorization: Bearer dge_YOUR_KEY" \
  -H "Accept: application/json"

Orders

Orders let you measure what each campaign sells, start Makes a purchase in the shop automations and close abandoned carts. Buyers don’t become contacts: we keep an order only if the buyer is already one of your contacts or came from a campaign link (see Sales from campaigns). The others are discarded.

POST /orders

Records an order or updates its status. Send it when it’s created and again at every change (payment, refund, cancellation), always with the same id.

FieldTypeDescription
idrequiredstringYour id for the order, up to 64 characters.
statusrequiredstringpending (awaiting payment), paid, refunded (fully refunded) or cancelled.
totalrequirednumberThe total the customer paid, including taxes and shipping.
emailstringThe buyer’s email: it links the order to the contact with the same address.
numberstringThe order number the customer sees, if different from the id.
refundednumberHow much has been refunded so far. For a partial refund, leave status as paid and put the amount here.
currencystringThe currency code. If missing, the site’s currency applies.
created_atstringThe order’s date and time. If missing, the moment we receive it applies.
click_idstringThe value of the digo_c cookie, if present: it links the order to the campaign.
itemsarrayThe order lines, up to 200.
items[].namerequiredstringThe product name.
items[].quantityrequiredintegerThe quantity, at least 1.
items[].totalrequirednumberThe line total.
items[].idstringThe product id, the same as in PUT /items: automations that start for a specific product need it.

Request

curl -X POST https://www.digo.email/api/v1/orders \
  -H "Authorization: Bearer dge_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "id": "5531",
    "number": "#5531",
    "email": "emma.wilson@example.com",
    "status": "paid",
    "total": 43.80,
    "refunded": 0,
    "currency": "EUR",
    "created_at": "2026-10-20T10:15:00+02:00",
    "click_id": "184467.9f1c2ab07d3e4f51",
    "items": [
      { "id": "1042", "name": "Glazed ceramic mug", "quantity": 2, "total": 39.80 }
    ]
  }'

Response · 200

{ "attributed": true }

attributed is true when the order counts for a campaign. An order that concerns neither a contact nor a campaign isn’t kept, and the response is {"attributed": false, "stored": false}.

  • When an order becomes paid for the first time and the buyer is a contact, the Makes a purchase in the shop automations start.
  • A pending or paid order closes the buyer’s open carts: abandoned cart emails no longer go out.
  • Reports count paid orders, minus refunds. Pending and cancelled orders don’t count.

POST /orders/history

Imports past orders, up to 100 per request, inside orders and with the same fields as POST /orders. The same rules apply, but these orders describe what has already happened: they don’t start automations or close carts. You can send them again: they update the same orders. An invalid email simply matches no contact.

Request

curl -X POST https://www.digo.email/api/v1/orders/history \
  -H "Authorization: Bearer dge_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "orders": [
      { "id": "4870", "email": "emma.wilson@example.com", "status": "paid", "total": 24.00, "created_at": "2026-03-02T17:40:00+01:00" },
      { "id": "4871", "email": "james.taylor@example.com", "status": "refunded", "total": 58.50, "refunded": 58.50, "created_at": "2026-03-03T09:12:00+01:00" }
    ]
  }'

Response · 200

{ "received": 2, "stored": 1 }

received counts the orders received, stored those kept because they belong to your contacts or came from a campaign.

Carts

With carts you can remind customers what they left in your shop, with the Abandons their cart automation. In emails, the placeholders {{carrello_link}}, {{carrello_totale}} and {{carrello_prodotti}} show the link to resume the cart, the total and the products.

PUT /carts

Saves the cart of a customer whose email you know, because they signed in or typed it at checkout. Send it again at every change, always with the same id. We keep only the carts of people who are already your contacts: nobody becomes a contact by filling a cart.

FieldTypeDescription
idrequiredstringYour id for the cart, up to 64 characters.
emailrequiredstringThe customer’s email.
totalrequirednumberThe cart total.
urlrequiredstringThe address that reopens this cart, from another device too: it’s the link of the button in emails. If it isn’t valid, we use the site’s address.
itemsrequiredarrayThe products, from 1 to 100, with name, quantity and total required, id and image (the image’s full address) optional.
currencystringThe currency code. If missing, the site’s currency applies.

Request

curl -X PUT https://www.digo.email/api/v1/carts \
  -H "Authorization: Bearer dge_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "id": "c-8f2a1c",
    "email": "emma.wilson@example.com",
    "total": 39.80,
    "currency": "EUR",
    "url": "https://www.yoursite.com/cart?resume=8f2a1c",
    "items": [
      { "id": "1042", "name": "Glazed ceramic mug", "quantity": 2, "total": 39.80, "image": "https://www.yoursite.com/media/glazed-mug.jpg" }
    ]
  }'

Response · 200

{ "saved": true }

If the email isn’t one of your contacts, the response is {"saved": false} and any cart saved earlier with the same id is removed.

DELETE /carts/{id}

Closes a cart the customer has emptied. It answers 204, with no content. After a purchase it isn’t needed: the order already closes the buyer’s carts.

Request

curl -X DELETE https://www.digo.email/api/v1/carts/c-8f2a1c \
  -H "Authorization: Bearer dge_YOUR_KEY" \
  -H "Accept: application/json"

Sales from campaigns

To tell you what each campaign sells, DIGO Email links orders to clicks in emails:

  1. When someone clicks a link in the email that leads to your site, we add the digo_c parameter to the address, for example https://www.yoursite.com/products/glazed-mug?digo_c=184467.9f1c2ab07d3e4f51. This applies to the site address set in Integrations and to its subdomains.
  2. If the visitor has accepted marketing cookies, your site stores the value in the digo_c cookie for 7 days. A more recent click replaces the previous one.
  3. When the customer buys, you send the cookie’s value as click_id with the order.

The order counts for the campaign if it arrives within 7 days of the last click on that email. If the customer clicked several emails, the last one counts.

JavaScript, on every page of the site

<script>
(function () {
  var click = new URLSearchParams(location.search).get('digo_c');
  if (!/^\d{1,19}\.[a-f0-9]{16}$/.test(click || '')) return;
  if (!hasMarketingConsent()) return; // your cookie banner’s check
  document.cookie = 'digo_c=' + click + '; path=/; max-age=604800; SameSite=Lax; Secure';
})();
</script>

PHP, when you send the order

$order['click_id'] = $_COOKIE['digo_c'] ?? null;
digo_c is a marketing cookie: store it only with the visitor’s consent and list it in your cookie policy (marketing category, 7-day duration, used to attribute sales to email campaigns). If the visitor accepts cookies after the page has opened, run the check again when the banner records their choice.

Linking only works with click tracking turned on, in Settings › Business › Track opens and clicks: without it, email links lead straight to the site and carry no digo_c.

Good practice

  • Call the API from your server, never from the browser: the key must never leave it.
  • Don’t keep customers waiting. At checkout, queue sign-ups, orders and carts and send them right after: if DIGO Email is slow or unreachable, the purchase must not get stuck.
  • Retry calmly after a network error, a 429 or a 5xx, waiting a little longer each time. Requests with other 4xx errors need fixing, not repeating.
  • Ask for consent with a checkbox to tick, not a pre-ticked one, and send in consent_text exactly the text the person read.
  • Send the language of whoever signs up with language: confirmation emails, campaigns and unsubscribe pages will follow it.
  • Keep your catalogue up to date: send products when they change and remove them when they’re no longer on sale.
  • Test with a test list and your own addresses. Test sign-ups are real contacts: they count towards your limit and, with double opt-in, receive real emails. Delete them from the dashboard when you’re done.

Support

For questions about the API, write to info@digo.email. Include the name of the connected site, the endpoint and the response you received: never the key.