Getting Started
Listo exposes three integration surfaces. Most partners use the first two together; the third is independent.
| Surface | What it's for | Base host |
|---|---|---|
| REST API | Read clients, workers, users, and org structure on installations of your integration. | https://gateway.listoglobal.com |
| Webhooks | Receive signed HTTP pushes when domain entities change in Listo (HMAC-SHA256, Standard Webhooks v1). | Outbound from gateway.listoglobal.com |
| OAuth 2.0 / SSO | Let Listo users sign in to your app with their Listo identity (OIDC). | https://api.dashboard.listoglobal.com |
This page walks you through the REST API end-to-end — provisioning, authentication, your first call — and points to the right next page for each surface.
Note: OAuth/SSO has its own credential model (client ID + client secret + redirect URI), its own host, and its own setup. Skip directly to OAuth2.0 & SSO if that's the only surface you need.
1. Concepts you'll see
Three terms appear in every endpoint and payload. Internalize them before you write code.
| Concept | What it is |
|---|---|
| External Integration | Your company's integration with Listo. Owns the API key and (for webhooks) the signing key. One per partner. |
| Application Instance | A Listo deployment — a customer's tenant. |
| Instance Integration | The installation of your External Integration on a single Application Instance. Most resources are scoped to one of these. Often called the instanceIntegrationId in URLs. |
Public IDs are opaque strings with stable prefixes you can rely on for routing in your code:
| Entity | Prefix | Looks like |
|---|---|---|
| Client | lglsocli_ | lglsocli_uZIIHfKqYBwyaRGGs |
| Worker | lglsowpr_ | lglsowpr_uZIIQiu8Q5zhUXgbR |
| Webhook event | lglsoevt_ | lglsoevt_uZJK2rPmA1nGqvE5w |
Treat IDs as opaque — match on them, don't parse them.
2. What you need from Listo
Before your first request, ask the Listo team to provision:
- API key — 64-character secret. Carried in the
x-api-keyheader on every REST request. Listo only stores a SHA-256 hash, so the plaintext is shown once. - Allowed domains — the hostnames your servers will call Listo from. Listo rejects requests whose
Hostdoes not match an allowed entry (exact match or*.example.comwildcard). This is the same list that gates webhook destination URLs. - (Webhooks only) Webhook signing key —
whk_…, base64url. Distinct from the API key. Used to verify the HMAC on inbound deliveries. Also shown once. - (OAuth/SSO only) Client ID, client secret, redirect URIs — see the OAuth2.0 & SSO guide.
Store every secret in a secret manager. None of them can be recovered from Listo after issuance — only rotated.
3. Authenticate
Every REST call requires the API key as a header:
x-api-key: your-64-character-api-key-here
Production base URL:
https://gateway.listoglobal.com
Heads up — allowed domains. If your call returns
401even with a valid key, the most common cause is that your outboundHostis not on your allowed-domains list with Listo. Confirm with the Listo team before debugging headers.
4. Your first call
Every other endpoint is scoped under an instanceIntegrationId. The canonical first call discovers them.
cURL
curl -X GET https://gateway.listoglobal.com/v1/external-integration/installations \
-H "x-api-key: your-64-character-api-key-here"Node.js
const res = await fetch(
'https://gateway.listoglobal.com/v1/external-integration/installations',
{ headers: { 'x-api-key': process.env.LISTO_API_KEY } },
);
const installations = await res.json();Python
import os, requests
r = requests.get(
'https://gateway.listoglobal.com/v1/external-integration/installations',
headers={'x-api-key': os.environ['LISTO_API_KEY']},
timeout=30,
)
r.raise_for_status()
installations = r.json()A 200 OK returns an array of installations:
[
{
"id": "inst_abc123xyz",
"applicationInstance": { "instanceName": "Acme Corp Production" },
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-20T14:22:00.000Z"
}
]The id field is your instanceIntegrationId for every per-installation endpoint that follows. Cache it — it's stable.
5. Errors
All errors share a single shape:
{ "statusCode": 401, "message": "Invalid API key" }| Code | Meaning | Likely cause |
|---|---|---|
400 | Bad Request | Required parameter missing or malformed. |
401 | Unauthorized | API key missing/invalid, or Host not on your allowed-domains list. |
404 | Not Found | The installation/resource doesn't exist or isn't yours to read. |
500 | Server Error | Listo-side failure. Safe to retry with backoff. |
Treat 4xx as your bug, 5xx as transient.
6. Where to go next
REST API — read entities
Browse every endpoint, parameter, and response schema in the API Reference. The reference is interactive — paste your API key into the "Try It" panel and call live.
The endpoints are organized around a single hierarchy:
/v1/external-integration/installations
/v1/instance-integrations/{instanceIntegrationId}/clients
/v1/instance-integrations/{instanceIntegrationId}/clients/{clientId}/users
/v1/instance-integrations/{instanceIntegrationId}/clients/{clientId}/job-titles
/v1/instance-integrations/{instanceIntegrationId}/clients/{clientId}/organization-structure
/v2/instance-integrations/{instanceIntegrationId}/clients/{clientId}/workers
…
If you only have a workerId and not the surrounding installation context, there is also a flat lookup variant under /v1/.../workers/{workerId}.
Webhooks — receive real-time events
Listo pushes events to URLs you register per installation. Read the four guide pages in order — they are designed to be followed front to back when you're integrating for the first time:
- Webhooks overview — wire format, headers, the
DomainEventenvelope, versioning. - Subscribing to webhooks — how Listo registers your URL against an installation, signing-key handling, rotation.
- Verifying webhook signatures — copy-paste verifier code; mandatory before processing any payload.
- Delivery, retries, and idempotency — at-least-once delivery, retry schedule, dedupe-by-
webhook-id.
Then pick the events your integration cares about from the Event Catalog:
OAuth 2.0 / SSO — sign Listo users into your app
Different host (api.dashboard.listoglobal.com), different credentials (client ID + secret + redirect URIs), different flow (Authorization Code with optional PKCE). Full walkthrough in OAuth2.0 & SSO.
7. Pre-flight checklist
Before you ship to production:
- API key stored in a secret manager — not in source, not in environment files committed to git.
- Every hostname your production servers call from is on your allowed-domains list with Listo.
- You discover installations via
GET /v1/external-integration/installationsrather than hardcodinginstanceIntegrationIdvalues. - You retry
5xxwith exponential backoff. You don't retry4xx. - (If using webhooks) Your handler verifies signatures against raw bytes (not parsed JSON), enforces the 5-minute timestamp window, and dedupes on the
webhook-idheader. - (If using webhooks) Your handler tolerates unknown event types and unknown fields — return
200 OKand log, don't4xx. - (If using OAuth) You validate the
stateparameter, validate the ID-token signature against the JWKS, and store tokens inhttpOnlycookies (web) or secure storage (mobile).
If any of these can't be checked yet, the linked guides above tell you exactly how to get there.
Updated 1 day ago
