---
title: "OneStream API Reference"
description: "Reference for the OneStream compatibility flavor of the Panel API. Raw JSON, X-Api-Key, opaque line UUIDs, and rid-based idempotency."
---

# OneStream API Reference

The OneStream API Reference documents the `/panel-api/onestream/ext/*` surface. It exists to make one thing painless: pointing an integration that already speaks OneStream at Xtream AI without rewriting the client. Every documented endpoint accepts the same headers, the same body shape, and the same `rid` idempotency semantics your OneStream code already sends. In most migrations the only mandatory change is the base URL.

If you are starting a brand-new integration instead of migrating one, you should not be reading this. Prefer the [native v1 API](/docs/?page=xai-ref-overview) and the [official SDKs](/docs/?page=panel-api-sdks). Both are more consistent, better typed, and give you the same data. The OneStream flavor is a compatibility surface: it is stable and supported, but its shapes carry OneStream history that new code does not need to inherit.

## Base URL and authentication

Every endpoint in this reference lives under a single base:

```
https://<your-panel-domain>/panel-api/onestream/ext/*
```

Replace `<your-panel-domain>` with the domain your customers already use to reach the panel. Each per-endpoint page states the exact `/ext/<path>` it appends.

Authentication uses one header. Any of three names is accepted, so the token can travel under whichever your OneStream client already sends:

```
X-Api-Key: <your-api-key>
X-Auth-User: <your-api-key>
Authorization: Bearer <your-api-key>
```

The first header present on the request wins. `X-Api-Key` is the canonical OneStream header and the one this documentation uses in examples. `X-Auth-User` is the legacy header from earlier OneStream releases, still accepted so that older client code keeps working. `Authorization: Bearer` is offered for modern SDKs that standardized on RFC 6750.

Get an API key from **Settings, Panel API Keys** in the Xtream AI panel. See [Authentication](/docs/?page=panel-api-authentication) for the full contract, scopes, and IP allow-listing.

A canonical smoke test after a base URL swap:

```bash
curl -H "X-Api-Key: <your-api-key>" \
     https://<your-panel-domain>/panel-api/onestream/ext/profile
```

A 200 with a JSON object confirms the token reached the panel and was accepted. A 401 with `{"error":"Invalid API key"}` means the token was not accepted; check the exact string you pasted and the key's IP allow-list.

## Line IDs are opaque

Every `line_id` in this reference is a UUID that looks like `550e8400-e29b-41d4-a716-446655440000`. It is not a random identifier and it is not a database primary key. Under the hood it is an opaque token: the panel encodes the internal numeric line id together with an HMAC signature scoped to the calling license, so the string has the exact shape a legacy OneStream client expects while remaining unforgeable and tenant-isolated.

Three consequences worth internalizing before you write code against this API.

1. **Cross-license IDs return 404 uniformly.** A UUID minted by panel A does not resolve on panel B, even if the underlying line number happens to coincide. The API does not distinguish "the UUID was never issued", "the UUID is malformed", and "the UUID belongs to another license". All three answer with the same 404. This is a deliberate contract: the response cannot be used as an oracle to discover which lines exist on another tenant.

2. **The UUID is stable as long as the panel's opaque secret does not rotate.** Store the UUID next to your own records at creation time and reuse it. Do not try to derive it from the numeric id, do not try to decode it, and do not assume a bijection with any user-visible number.

3. **A tampered UUID is rejected up front.** Flipping a single hex digit invalidates the HMAC and the request returns `422 line_id not found or invalid`. Constant-time comparison is used so timing cannot leak information about which digits were "closer" to a valid signature.

The mechanism is documented in more depth in the [OneStream compatibility notes](/docs/?page=panel-api-onestream-compatibility#line-uuids-opaque).

## Idempotency by `rid`

OneStream integrations attach an `rid` (request or transaction identifier) to every write. Xtream AI honors this exactly.

- Pass a unique `rid` in the JSON body of every `POST`. UUIDs, ULIDs, or any string up to 255 bytes work.
- If the same `rid` is retried with the same body, the API replays the original response verbatim, including the original HTTP status and JSON body. Side effects run at most once.
- If the same `rid` is retried with a different body, the API returns `409 idempotency_conflict` (`Transaction already processed`). The original transaction is not touched.
- Idempotency records survive at least 24 hours, so any realistic retry loop is covered.

If a `POST` times out and you never saw the response, do not blindly retry. Call [`GET /ext/transaction/{rid}`](/docs/?page=os-ref-transaction) first with the same `rid`. If it returns 200, use the cached response and treat the write as complete. If it returns 404, the write never reached the panel and you can safely retry with the same `rid`.

For the full retry contract, see [Rate limits and Idempotency](/docs/?page=panel-api-rate-limits-idempotency).

## Response shape

OneStream does not use the v1 envelope. Success responses are raw JSON objects on a 2xx status, without a wrapping `{status, data}`. List endpoints return either a plain JSON array (`/ext/packages`, `/ext/bouquets`, `/ext/lines`, `/ext/user/find`) or an object shaped as `{status, data: {pagination, items}}` (only `/ext/lines/index`, kept for callers that already parse OneStream's paginated envelope).

Error responses are the same shape OneStream returns: a plain object `{"error": "<message>"}` on the appropriate HTTP status code. When the failing request carried an `rid`, the response body also carries it under an `rid` key so a retry can correlate with the original attempt. The full slug to message map is on the [OneStream compatibility notes](/docs/?page=panel-api-onestream-compatibility#errors).

Booleans are real JSON booleans (`true`, `false`), timestamps are ISO 8601 with an explicit offset, and numeric ids are numbers, not strings.

## What is supported and what is not

Every endpoint listed below is served by the OneStream dialect. The read endpoints have per-page reference in this section; the write endpoints are documented in the OneStream Writes section.

| Endpoint | Reference page |
|---|---|
| `GET /ext/profile` | [Profile](/docs/?page=os-ref-profile) |
| `GET /ext/packages` | [Packages](/docs/?page=os-ref-packages) |
| `GET /ext/bouquets` | [Bouquets](/docs/?page=os-ref-bouquets) |
| `GET /ext/lines`, `GET /ext/lines/index` | [List lines](/docs/?page=os-ref-lines-list) |
| `GET /ext/line/find` | [Find line by username](/docs/?page=os-ref-lines-find) |
| `GET /ext/user/find` | [Find sub-reseller](/docs/?page=os-ref-users-find) |
| `GET /ext/transaction/{rid}` | [Look up a transaction](/docs/?page=os-ref-transaction) |
| `POST /ext/line/create`, `create-advanced` | [OneStream compatibility](/docs/?page=panel-api-onestream-compatibility#post-ext-line-create) |
| `POST /ext/line/{uuid}/renew` | [OneStream compatibility](/docs/?page=panel-api-onestream-compatibility#post-ext-line-uuid-renew) |
| `POST /ext/line/{uuid}/enable`, `/disable` | [OneStream compatibility](/docs/?page=panel-api-onestream-compatibility#post-ext-line-uuid-enable-disable) |
| `POST /ext/line/{uuid}/terminate` | [OneStream compatibility](/docs/?page=panel-api-onestream-compatibility#post-ext-line-uuid-terminate) |
| `POST /ext/line/{uuid}/update-advanced` | [OneStream compatibility](/docs/?page=panel-api-onestream-compatibility#post-ext-line-uuid-update-advanced) |
| `POST /ext/user/create`, `/update`, `/credit` | [OneStream compatibility](/docs/?page=panel-api-onestream-compatibility#post-ext-user-create) |

`GET /ext/live_connections/*` returns `501 not_implemented` by design. There is no global live-connections listing or global kill in this API. Per-line connection listing is available on the native surface at [`GET /panel-api/v1/lines/{id}/connections`](/docs/?page=xai-ref-lines-connections). This is an operator decision, not an oversight, and the compatibility dialect will not change to expose it.

Any other path under `/ext/*` that this reference does not list also returns `501 not_implemented`.

## See also

- [OneStream compatibility notes](/docs/?page=panel-api-onestream-compatibility) with the full endpoint mapping, field translations, and migration gotchas.
- [Panel API Overview](/docs/?page=panel-api-overview) for how the three flavors fit together.
- [Native v1 API Reference](/docs/?page=xai-ref-overview) for new integrations.
- [Rate limits and Idempotency](/docs/?page=panel-api-rate-limits-idempotency).
- [Errors](/docs/?page=panel-api-errors).
