Fetchit

Switch to dark theme

REST API

Getting startedStart here

Get a credential, make your first authenticated request, and learn the conventions every Fetchit endpoint shares.

Where a key comes from, what a first call looks like, and how to read the answer.

Published

This page takes you from nothing to one successful authenticated request. It assumes you have read nothing else. The Authentication page behind it is the specification; this one is the path through it.

1. Get a credential

A credential is a pair: a Client ID, which names the key, and a Client Secret, which proves it. There are two ways to be holding one.

  • You run a clinic's account. Sign in, open your organization's manage page, and create a key under Programmatic access. You need the org.keys.create act, which the organization's Admin role holds by default. The key you create is locked to your organization and can only ever act on it.
  • You are a partner, or you are building the desktop client. Ask Schultz Technology. Keys that are not locked to a clinic are not self-service, and a request carrying one has to identify its clinic some other way. See non-federated keys.
The secret is shown once

The server stores only a SHA-256 hash of the secret and the last eight characters, for display. The response or dialog that creates a key is the only time the full secret exists anywhere outside your own storage. If you lose it, you rotate the key. Nobody can recover it for you.

2. Make a request

Send the pair as headers. Nothing else is required to authenticate.

A first authenticated request
curl -sS -X POST https://www.fetchitdata.cloud/api/v1/calls/events \
  -H "Client-ID: $FETCHIT_CLIENT_ID" \
  -H "Client-Secret: $FETCHIT_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
        "type": "call_received",
        "providerCallId": "demo-0001",
        "occurredAt": "2026-09-04T14:32:05.120Z",
        "call": {
          "direction": "inbound",
          "from": { "kind": "e164", "number": "+15550104242", "name": "DOLITTLE JANE" },
          "to": { "kind": "extension", "extension": "101" }
        }
      }'

That endpoint needs a key federated to an organization and holding org.calls.events. A key that is not locked to a clinic gets a 403 saying so, which is itself a useful confirmation that the credential is being read.

If your HTTP client has already claimed the Authorization header for something else, or if you would rather carry one value than two, the same secret works as a bearer token. See the header forms.

3. Read the answer

Success is a 200 or a 201 and an object whose success is true.

201 Created
{
  "success": true,
  "calls": [
    {
      "id": "cm1f8q0a70000abcd1234wxyz",
      "providerCallId": "demo-0001",
      "created": true,
      "crmClients": [ { "externalId": "8812", "name": "Jane Dolittle" } ]
    }
  ],
  "events": [
    {
      "id": "cm1f8q0a80001abcd5678wxyz",
      "type": "call_received",
      "dedupeKey": "call_received:0",
      "duplicate": false
    }
  ]
}

201 when the request created a call, 200 when every call in it already existed. duplicate on an event is how a reporter retrying after a timeout tells a landed retry from a silent failure.

Failure is the same envelope inverted, with a sentence saying what to do about it.

403 Forbidden
{
  "success": false,
  "error": "403 Forbidden",
  "message": "The provided API key may not report call_recorded."
}

Branch on the HTTP status and on success. Do not parse message, it is written for people and its wording will change.

What to check when it does not work

Work down this list in order. The first three cover almost everything.

  1. 401 Unauthorized. No live key matched. Either no credential arrived, the secret is wrong, the key was revoked, or it has expired. Revocation and expiry are enforced in the lookup itself, so a key that stopped working stopped working the instant it was revoked.
  2. 403 Forbidden, naming a scope. The key authenticated and is not permitted this act. Add the named scope to the key, or use a key that holds it. Rotating will not help.
  3. 403 Forbidden, mentioning federation. The key is not locked to a clinic, and the endpoint serves one. See Federation.
  4. 400 Bad Request. The body failed validation, and message lists each field and what was wrong with it.
  5. 503 Service Unavailable. Transient. Honour Retry-After and send the same request again.

Every response carries an X-Trace-ID header. Log it. When you need a specific request looked at, that id finds it.

Conventions worth knowing early

  • Identifiers are opaque strings. Do not parse them, do not assume a length, and do not assume a format.
  • Timestamps are ISO 8601 in UTC, both in request bodies and in responses.
  • Phone numbers are E.164 wherever the API takes one.
  • Unknown response properties are additive. Ignore what you do not recognise rather than failing on it. New optional properties are not a version bump.
  • Writes are addressed to the key's own organization. A tenant key does not name its clinic in the body; the key is the clinic. This is the point of federation, and it is why a leaked key is scoped to one practice rather than all of them.

Next

Read Authentication before you build anything real. It covers the header forms, federated and non-federated keys, the scope model and its one wildcard rule, and rotation.