Skip to content

Quickstart

1. Create a sandbox key

In Bodo: Settings › Interfaces › API keys › “Create key”.
Step in the wizardValue for the quickstart
Environmenttest, binds to “Musterfirma GmbH (Sandbox)”
ScopeContacts: read & write · Companies: read · Rest: no access
IP bindingyour current IP, e.g. 198.51.100.7/32 (required for writes)
Expiry30 days (default)
The API is already on in the sandboxYour organization’s sandbox already has apiAccess switched on, with test data only. So the quickstart needs no approval from an admin. The one precondition: your organization has declared in Bodo whether professional secrecy applies to it; without that declaration the API stays off in the sandbox as well. For a live key (live) an org admin first has to enable the API of your organization under Settings › Interfaces › API; until then the button is missing there.

The secret is shown only once. Keep it in an environment variable:

Shell
export BODO_API_KEY="bodo_uk_test_…"

2. Who am I?

GET /v1/me names the principal, the organization and your own key with expiry, pin and effective scopes.
Request
curl https://api.bodo-app.com/v1/me \
  -H "Authorization: Bearer $BODO_API_KEY"
Response
HTTP/1.1 200 OK
Bodo-Version: 2026-11-01
Request-Id: req_01JB6…

{
  "authMethod": "apiKey",
  "principalType": "user",
  "principalId": "usr_…",
  "principalName": "Max Mustermann",
  "organization": {
    "id": "org_…",
    "name": "Musterfirma GmbH (Sandbox)"
  },
  "key": {
    "kidShort": "…Kx9a",
    "environment": "test",
    "versionPin": "2026-11-01",
    "expiresAt": "2026-12-03T09:00:00Z"
  },
  "grant": null,
  "scopes": [
    "contacts:read",
    "contacts:write",
    "companies:read"
  ],
  "openFamilies": [],
  "apiVersion": "2026-11-01"
}

3. Create a contactPreview

Writes start in the preview channel and therefore need Bodo-Preview: true. With the first follow-up version, writes for contacts, companies and tasks move to stable and the header is no longer needed. Idempotency-Key is required for POST; with the same key a retry is safe.
curl
curl -X POST https://api.bodo-app.com/v1/contacts \
  -H "Authorization: Bearer $BODO_API_KEY" \
  -H "Bodo-Preview: true" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"firstName":"Erika","lastName":"Mustermann","email":"erika@musterfirma.de"}'

Or with the SDK, which sets the preview header and the idempotency key itself:

// Portal D2 · Quickstart — steps 2 and 3 with the SDK: who am I, then one contact.
// Run: BODO_API_KEY=bodo_uk_test_… bun examples/quickstart.ts
import { Bodo, BodoApiError } from "@bodo/api";

const bodo = new Bodo({
  apiKey: process.env.BODO_API_KEY,
  preview: true, // writes are in the preview channel: sends Bodo-Preview: true
});

// Step 2 · Who am I?
const me = await bodo.me();
console.log(me.principalType, me.authMethod);

// Step 3 · Create a contact. The SDK sets the Idempotency-Key itself, retries included.
try {
  const contact = await bodo.contacts.create({
    firstName: "Erika",
    lastName: "Mustermann",
    email: "erika@musterfirma.de",
  });
  console.log(contact.id, contact.displayName);
} catch (err) {
  if (err instanceof BodoApiError) {
    console.error(err.code, err.requestId); // the stable code, never the text
  }
  throw err;
}
  • 201 Created
  • Location: /v1/contacts/con_…
  • ETag

4. Look it up in Bodo

The contact is in the sandbox. Its timeline shows the plug mark, so the origin is visible.
Max Mustermann created the contact Erika Mustermann, via the API.Done through the APISandboxjust now