API, Webhooks & Audit

The Dinopix REST API

Pull your reviews, customers and survey responses into your own systems with an Enterprise API key, or send surveys from them with Surveys Pro.

What it is

An HTTP API with two kinds of key:

  • Read keys pull your own data into a warehouse, a BI tool or your own application. They are available on the Enterprise plan.
  • Send-only keys send a survey to a customer when something happens in your own systems, such as a booking system marking an appointment done. They come with Surveys Pro, which Enterprise includes. See Sending a survey below.

A read key can't send and a send-only key can't read anything. Apart from sending a survey, the API doesn't write: anything that writes to a customer-facing platform goes through the app, where the safeguards live.

Creating a key

  1. Go to Settings, then API keys.
  2. On Enterprise, choose Read data or Send surveys. With Surveys Pro alone, every key is send-only.
  3. Give the key a name describing where it will be used, such as "Data warehouse sync" or "Booking system".
  4. Copy the key immediately. It is shown once and never again, because only a hash of it is stored.
Settings > API keys

Copy your API key now. You will not see it again.

dpx_live_7f3a91c4e08b42d6ae5c1b9f2d740e63

Data warehouse syncReads dataUsed 12 minutes agoRevoke
Booking systemSends surveysUsed 3 minutes agoRevoke
Old Zapier testReads dataRevokedRevoked
e.g. Data warehouse sync
Create a key

A key is scoped to one business. If you run several, create a key per business. Revoking is instant and cannot be undone, so create the replacement first, swap it in, then revoke the old one. Only owners and admins can create and revoke keys, and each one is recorded in the audit log.

Authenticating

Send the key as a bearer token:

Authorization: Bearer dpx_live_your_key_here

A missing, malformed or revoked key returns 401. A key used for the other job (a read key sending, or a send-only key reading) returns 403 with the code wrong_key. A key whose plan no longer includes it returns 403 with needs_enterprise or needs_pro.

Sending a survey

With a send-only key, one call sends one survey to one person:

POST /surveys/{survey_id}/send
Authorization: Bearer dpx_your_send_key
Content-Type: application/json

{"email": "customer@shop.com", "name": "Alex Taylor"}

email is required and name is optional. The survey id is shown on the API keys page, where you pick a survey and copy a ready-made example.

  • New people are added. If the email isn't one of your contacts (by any of their addresses), a contact is created with it. A name fills in a contact's name only when they don't have one.
  • It goes to the contact's main address. If the email is one of a contact's other addresses, the survey goes to their main one, as it would from Dinopix. The reply's to says where it went.
  • The usual rules apply. It isn't sent to anyone who unsubscribed, or who had a survey within the survey's limit (14 days at least), or a review request in the last 2 days. The survey goes from the same sender, with the same reminder, as when you send it from Dinopix.
  • Paused or draft surveys aren't sent. Pausing a survey in Dinopix stops your integration sending it too.
  • Retries can't email someone twice by accident. For 5 minutes after a call that sent a survey, or may have, another call for the same person is refused with duplicate, so a retry after a timeout can't send it twice. When a reply says it wasn't sent, you can try again straight away. After that, the survey limit stops a second email. If a reply says the survey may still arrive (unconfirmed), check the contact in Dinopix before sending again.

A sent survey returns 200:

{"sent": true, "send_id": "...", "to": "customer@shop.com", "contact_id": "...", "contact_created": false}

Anything else has an error to show a person and a code for your code to check:

  • 409 not sent: rate_limited (had a survey within the survey's limit), too_soon (had a review request in the last 2 days), suppressed (unsubscribed), survey_paused, duplicate (a survey to the same person is sending, just went, or may have) or sender_not_ready (the survey's email provider can't send just now; the error says why).
  • 400 a problem with the request: invalid_email, invalid_body, invalid_name, invalid_survey_id, undeliverable (an address that can't receive mail, such as @example.com) or survey_draft.
  • 404 no_survey: the survey isn't one of this business's. no_contact: the contact was deleted while the call ran.
  • 403 no_access: the person who created the key no longer has access to the business. Create a new key.
  • 405: anything but POST to the send address.
  • 429 too_many_requests: more than 60 calls a minute with one key, or 5,000 sends a day for the business. Wait for the Retry-After seconds. Calls refused before sending (a bad request, a paused survey, a repeat within 5 minutes) don't count towards the 5,000.
  • 500 server_error: something went wrong on our side before anything was sent. Try again.
  • 502 send_failed: the email didn't go, for example your own email provider refused it. The error says why. unconfirmed: we couldn't tell whether it went, so check the contact before sending again.
  • 503: the API is unavailable for a moment. Your key is fine; try again after Retry-After.

Sends from the API show as API on the contact's timeline and in the send log.

Resources

These need a read key.

  • GET /reviews returns platform, rating, author name, text, sentiment, whether it has been replied to, and the published date.
  • GET /contacts returns name, email, phone, company, tags and created date.
  • GET /companies returns name, domain, phone, address and created date.
  • GET /orders returns contact, kind, number, status, total, currency, and the ordered and delivered dates. kind tells a purchase apart from an enquiry.
  • GET /nps returns contact, score, comment and created date, for NPS surveys.
  • GET /survey_responses returns every survey response, NPS, CSAT and customer effort alike: the survey, scale, score and band (low, mid or high), the comment, each answer with its question, the topics the comment is about, the contact, location, follow-up status and created date. Filter with ?scale=nps, csat or ces, and ?survey_id=.

An unknown resource returns 404 with the list of valid ones in the body.

Paging

Every resource takes limit and offset. The default limit is 50 and the maximum is 200. Responses echo both back alongside data, so you can page until you get fewer rows than you asked for.

GET /reviews?limit=200&offset=400

Notes worth knowing

  • Reviews are scoped to the listings belonging to the key's business. A business with no listings returns an empty array, not an error.
  • Ordering is newest first for reviews, orders and NPS, and alphabetical for companies.
  • Fields are added over time, never silently removed. Parse defensively and ignore fields you do not recognise.
  • Each call stamps the key's last-used time, which is how you spot a key nothing is using any more.

Polling or webhooks?

Use the API for bulk reads and backfills. For "tell me when something happens", use webhooks instead of polling every minute.

Did this answer your question?

If not, ask and we will point you at the right page.

Contact support