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.
403 account_inactive.Getting started
- In the dashboard open Integrations. Under Connect a site enter the site’s name and address and choose Website as the platform.
- Press Connect and create key and copy the key that appears: it starts with
dge_and we show it only once. - 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/jsonand ask for responses withAccept: 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 sameidagain updates the item instead of creating another one. - Amounts in units of the currency, with a dot for decimals:
49.90, not4990. 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
messagefield of errors is written for people, in Italian, English, Spanish, French or German depending on theAccept-Languageheader or the account’s language. In your code, decide based on the HTTP status and theerrorfield, 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."
}
| Status | error | What it means and what to do |
|---|---|---|
401 | invalid_key | Missing, wrong or replaced key. Check the key or create a new one. |
403 | account_inactive | The account is still under review and doesn’t accept sign-ups. We’ll email you when it’s active. |
403 | account_suspended | Sending from the account is suspended and sign-ups are refused. Contact support. |
409 | contact_limit | Contacts 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. |
409 | privacy_missing | Only for GET /forms: the link to your privacy policy is missing. Add it in Settings › Business. |
422 | unknown_list | None 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 get429withRetry-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
| Method | Path | What it’s for |
|---|---|---|
| GET | /ping | Checks the key and the account’s status |
| GET | /lists | Lists, with their ids |
| GET | /tags | Tags |
| GET | /fields | Contacts’ custom fields |
| GET | /forms | Sign-up forms, ready to display |
| POST | /contacts | Subscribes a contact with their consent |
| PUT | /items | Creates or updates products and posts |
| DELETE | /items/{type}/{id} | Removes a product or a post |
| POST | /orders | Records an order or updates its status |
| POST | /orders/history | Imports past orders |
| PUT | /carts | Saves 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.
| Field | Type | Description |
|---|---|---|
store | string | The site’s name in Integrations. |
account | string | The name of the DIGO Email account. |
platform | string | The chosen platform: woocommerce, digo_sale or site (Website). |
can_send | boolean | true when the account is active and accepts sign-ups. |
status | string | pending (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" }
]
}
| Field | Type | Description |
|---|---|---|
key | string | The name to use in fields of POST /contacts. It’s also the placeholder in emails: {{birthday}}. |
label | string | The name shown in the dashboard. |
type | string | text, 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.
| Parameter | Type | Description |
|---|---|---|
lang | string | Optional, 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">withactionas its target; - the
emailfield and the fields infields, each with itsname, required whenrequiredistrue; - a
consentcheckbox next to theconsent_texttext and the link toprivacy_url, plus a hiddenconsent_textfield 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.
| Field | Type | Description |
|---|---|---|
emailrequired | string | The email address, up to 190 characters. |
list_idsrequired | array | The list ids, from 1 to 10 (GET /lists). Ids that don’t exist are ignored; if none exists the response is 422 unknown_list. |
consentrequired | boolean | Must be true: the person ticked the consent checkbox. |
consent_textrequired | string | The exact text of the checkbox the person ticked, up to 1,000 characters. We keep it as proof of consent. |
sourcerequired | string | Where they signed up: form (a form), checkout (a purchase) or registration (creating an account on your site). |
first_name | string | First name, up to 100 characters. |
last_name | string | Last name, up to 100 characters. |
fields | object | Custom 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. |
tags | array | Up to 10 tag names, of 60 characters at most. Tags that don’t exist are created. |
language | string | The 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. |
form | string | The form’s name, up to 190 characters: it appears in the contact’s history. |
page | string | The address of the page where they signed up. We keep only the domain and path, without anything after ? or #. |
ip | string | The visitor’s IP address, not your server’s: it’s part of the proof of consent. |
user_agent | string | The 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" }
| status | What it means |
|---|---|
subscribed | Subscribed. If they were already a contact, the lists and tags have been added. |
confirming | They must confirm from the email we sent them: one of the lists has double opt-in, or they unsubscribed in the past. |
limited | Sign-up saved, but this address has already received too many confirmation emails today: the link will arrive if they sign up again tomorrow. |
capped | Sign-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.
| Field | Type | Description |
|---|---|---|
itemsrequired | array | The items, up to 100. |
items[].typerequired | string | product or post. |
items[].idrequired | string | Your id for the item, up to 64 characters. |
items[].title | string | The name. Items without a name are skipped. |
items[].url | string | The page’s full address, with https://. Items without a valid address are skipped. |
items[].image | string | The image’s full address. |
items[].excerpt | string | A short description, up to 2,000 characters. HTML is removed. |
items[].price | number | The price, as the customer sees it. |
items[].sale_price | number | The discounted price: in emails it becomes the price, with the regular one struck through. |
items[].available | boolean | false if the product isn’t available. If missing, it’s true. |
items[].published_at | string | The 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.
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.
| Field | Type | Description |
|---|---|---|
idrequired | string | Your id for the order, up to 64 characters. |
statusrequired | string | pending (awaiting payment), paid, refunded (fully refunded) or cancelled. |
totalrequired | number | The total the customer paid, including taxes and shipping. |
email | string | The buyer’s email: it links the order to the contact with the same address. |
number | string | The order number the customer sees, if different from the id. |
refunded | number | How much has been refunded so far. For a partial refund, leave status as paid and put the amount here. |
currency | string | The currency code. If missing, the site’s currency applies. |
created_at | string | The order’s date and time. If missing, the moment we receive it applies. |
click_id | string | The value of the digo_c cookie, if present: it links the order to the campaign. |
items | array | The order lines, up to 200. |
items[].namerequired | string | The product name. |
items[].quantityrequired | integer | The quantity, at least 1. |
items[].totalrequired | number | The line total. |
items[].id | string | The 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
paidfor the first time and the buyer is a contact, the Makes a purchase in the shop automations start. - A
pendingorpaidorder 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.
| Field | Type | Description |
|---|---|---|
idrequired | string | Your id for the cart, up to 64 characters. |
emailrequired | string | The customer’s email. |
totalrequired | number | The cart total. |
urlrequired | string | The 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. |
itemsrequired | array | The products, from 1 to 100, with name, quantity and total required, id and image (the image’s full address) optional. |
currency | string | The 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:
- When someone clicks a link in the email that leads to your site, we add the
digo_cparameter to the address, for examplehttps://www.yoursite.com/products/glazed-mug?digo_c=184467.9f1c2ab07d3e4f51. This applies to the site address set in Integrations and to its subdomains. - If the visitor has accepted marketing cookies, your site stores the value in the
digo_ccookie for 7 days. A more recent click replaces the previous one. - When the customer buys, you send the cookie’s value as
click_idwith 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
429or a5xx, waiting a little longer each time. Requests with other4xxerrors need fixing, not repeating. - Ask for consent with a checkbox to tick, not a pre-ticked one, and send in
consent_textexactly 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.