> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Developer Portal: console, usage, keys, and webhook debug

> Use the Developer API to try endpoints in a browser console, track usage and spend, cap key permissions, debug webhooks, and stream platform events.

# Build with the Developer API

The [Developer API](/api-reference/overview) is the pillar behind Orbit's own developer dashboard — it is not a channel like SMS or Voice, it is the tooling you use *while integrating* with those channels. This guide walks through what it's for and when to reach for each piece: exercising an endpoint before you write code, watching usage and errors as you ship, capping what a key can do, debugging a webhook that didn't arrive, streaming the platform event feed into your own Kafka topic or HTTP collector, and registering a marketplace app that requests scoped access to a customer's org.

Every endpoint in this guide requires an `owner`, `admin`, or `developer` role on the calling key or session; read-only usage endpoints also accept `viewer`.

## Explore the API without leaving the dashboard

The try-it console proxies a request through your browser session using a key you supply, so you can hit any endpoint without copying `curl` into a terminal:

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/developer/try-it \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "method": "GET",
    "path": "/messages?limit=5",
    "api_key": "dv_live_sk_the_key_to_exercise"
  }'
```

The response wraps the real upstream `status_code`, `headers`, and `body` so failures (a `422` from a bad query param, a `429` from rate limiting) show up exactly as they would to your own code. `api_key` only accepts `dv_live_sk_`, `dv_test_sk_`, `dv_live_pk_`, or `dv_test_pk_` prefixed values — it will not forward a request signed with something else.

Pair it with two read-only catalogs when you're deciding what to integrate against:

* `GET /developer/sdks` — every official SDK (Node, web, Python, Go, PHP, Ruby, Java, C#) with its package name, install command, and a `published` flag. A `published: false` entry describes the *future* registry shape — don't ship an install command for it yet.
* `GET /developer/api-versions` — the dated version registry. Send `X-Api-Version: 2026-01-15` (or similar) on any request to pin a specific dated behavior; the response echoes back `resolved_version` so you can confirm what you actually got.

When the read you need spans related resources — a contact with its conversations and messages, or a segment with its contacts — the developer GraphQL surface returns that tree in one request instead of fanning out over per-resource REST endpoints. [Query the GraphQL surface](/guides/graphql-querying) covers the endpoints, the published schema, and the dashboard Explorer (Developer → GraphQL).

## Track usage and spend

Two endpoints answer "how is my integration doing" at different resolutions.

`GET /developer/usage-stats?period=7d` (`24h` / `7d` / `30d` / `90d`) rolls up messages per channel — sent, delivered, failed, and cost — for the developer dashboard's summary cards:

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/developer/usage-stats?period=7d" \
  -H "X-API-Key: dv_live_sk_your_key_here"
```

The `/developers/api-analytics/*` group goes deeper, over raw HTTP request telemetry rather than message sends:

| Endpoint                                    | Answers                                                                                   |
| ------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `GET /developers/api-analytics/overview`    | Request volume, success/error split, latency percentiles                                  |
| `GET /developers/api-analytics/endpoints`   | Per-endpoint request count, error rate, latency                                           |
| `GET /developers/api-analytics/timeseries`  | Gap-filled time series for charting volume and errors                                     |
| `GET /developers/api-analytics/rate-limits` | How close each bucket is running to its configured cap                                    |
| `GET /developers/api-analytics/by-key`      | Per-key attribution — volume, last-used-at, last-used-ip                                  |
| `POST /developers/api-analytics/ask`        | Plain-English question over your own telemetry, e.g. `"what's my p95 latency this week?"` |

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/developers/api-analytics/ask \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "question": "which endpoints error the most today?" }'
```

## Govern what each key can do

`GET /developer/governance` returns the org-wide default requests-per-minute cap and monthly quota, plus every key's effective limits, live usage, and whether it has crossed the alert threshold:

```bash theme={null}
curl https://api.orbit.devotel.io/api/v1/developer/governance \
  -H "X-API-Key: dv_live_sk_your_key_here"
```

Tighten (or loosen, within platform bounds) one key without touching the org default:

```bash theme={null}
curl -X PUT https://api.orbit.devotel.io/api/v1/developer/governance/keys/key_abc123 \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "requests_per_minute": 60, "monthly_request_quota": 100000 }'
```

Send `null` on a field to make that key inherit the org default again; `PUT /developer/governance/org` changes the org-wide default the same way. Only the fields you send change — omitted fields keep their current value.

## Debug your inbound webhook deliveries

`GET /developer/inbound-webhooks` lists every inbound webhook call your endpoint received (or should have), and `GET /developer/inbound-webhooks/:id` returns one call's full request/response detail — the fastest way to answer "did Orbit actually send this, and what did my server say back":

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/developer/inbound-webhooks?limit=20" \
  -H "X-API-Key: dv_live_sk_your_key_here"
```

See [Webhooks → Security](/webhooks/security) for verifying the signature on what you receive.

## Stream platform events to your own infrastructure

If you'd rather consume Orbit's event feed (`message.*`, `call.*`, and the rest of the [webhook event taxonomy](/reference/webhook-events)) as a stream instead of one HTTP callback per event, configure a sink. `kind` is `kafka` or `http_batch`:

```bash theme={null}
curl -X PATCH https://api.orbit.devotel.io/api/v1/developer/event-sinks/http_batch \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled": true,
    "destination": { "kind": "http_batch", "url": "https://collector.example.com/ingest" },
    "credentials": "Bearer your-collector-token"
  }'
```

`GET /developer/event-sinks/:kind` reads the config back — the credential is write-only and never returned in plaintext, only a `credentials_configured` flag.

The inverse direction — pulling your own Kafka topic *into* Orbit — is the event-source surface. Configure it the same way, then dry-run one batch before wiring up a permanent consumer:

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/developer/event-sources/kafka/consume-batch \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "topic": "orbit.events.sample",
    "messages": [
      { "partition": 0, "offset": 1001, "value": "{\"type\":\"custom.example\"}" }
    ]
  }'
```

`consume-batch` runs one polled batch through Orbit's validation and returns the per-message disposition — no broker connection is opened and nothing is persisted, so it's safe to run against production credentials while you're still mapping your event types.

## Register a marketplace OAuth app

Building an app that requests scoped access to a customer's Orbit org (rather than using your own API key) goes through the OAuth app surface:

1. `GET /developers/oauth/scopes` — the closed catalog of grantable scopes (e.g. `messages:read`, `contacts:write`), each with its consent-screen label.
2. `GET /developers/oauth/consent-preview?scope=messages:read%20contacts:write` — renders the exact consent rows a customer would see for a scope string, and flags any scope outside the grantable catalog before you ship a request that would be rejected.
3. `GET /developers/oauth/manifest` — downloads the deterministic client-registration manifest, pre-wired to your org's API host, as `orbit-<your-org>.oauth-app.json`.

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/developers/oauth/consent-preview?scope=messages:read%20contacts:write" \
  -H "X-API-Key: dv_live_sk_your_key_here"
```

## Automate without writing an SDK integration

For no-code and low-code workflows, download a pre-wired definition instead of hand-rolling requests:

* `GET /developers/postman-collection` / `GET /developers/postman-environment` — a full Postman collection covering every public endpoint, plus an environment pre-filled with your base URL and org id (the API-key variable ships blank for you to paste in).
* `GET /developers/connector/zapier`, `GET /developers/connector/make`, `GET /developers/connector/n8n` — platform-specific app/blueprint/node-pack definitions for Zapier, Make, and n8n. `GET /developers/connector/catalog` lists every trigger and action across all three without downloading the full definitions.
* `GET /developers/cdp-sdk/catalog` and `GET /developers/cdp-sdk/source/:platform` (`web` / `ios` / `android`) — drop-in client tracking SDKs, pre-wired to your org's ingest host, for sending [Customer Data Platform](/api-reference/endpoints/cdp) events straight from a browser or mobile app.

All of these are downloads (`Content-Disposition: attachment`) meant to be imported directly into the target tool, not parsed as an API response.

## Frequently asked questions

### Does the try-it console work with a live production key?

Yes — it proxies to the real API using whichever key you supply, live or test. Anything it returns is exactly what your own integration would get back, including errors and rate limiting.

### Can I set a rate limit lower than the org default for one key but not others?

Yes. A per-key override in `/developer/governance/keys/:keyId` always wins over the org-wide default for that one key; every other key keeps inheriting the default.

### What happens to event-sink deliveries if my collector is down?

Configuration and delivery are separate: this API only manages the sink's config and credentials. The delivery worker that reads the config and pushes matching events records `last_run_*` status fields back onto the same config — check `GET /developer/event-sinks/:kind` for the latest run status.

### Do I need a marketplace OAuth app just to call the API myself?

No — OAuth apps are for building something a *different* Orbit customer installs into their own org. If you're integrating your own org's API key, skip straight to [Authentication](/authentication).

## See also

* [API Reference overview](/api-reference/overview) — the full endpoint catalog these tools operate on
* [Authentication](/authentication) — API key formats, roles, and rotation
* [Webhooks](/webhooks/overview) — the per-event HTTP push surface event sinks complement
* [Per-API-key IP allowlist](/guides/api-key-ip-allowlist) — another per-key control alongside rate-limit governance
