# Quickstart
> Source: /guides/quickstart
> Authenticate against the sandbox and make your first Partner API call.

This takes you from nothing to a verified call against the partner sandbox.

## 1. Choose an environment [#1-choose-an-environment]

Staging doubles as the partner sandbox — there is no separate one. Build and
test there, then move to production.

| Environment | Base URL |
|---|---|
| Sandbox (staging) | `https://api-stg.cf.journey.com/v1` |
| Production | `https://api-prd.cf.journey.com/v1` |

<Warning>
  The version is already in the base URL and in every path you will see in the
  reference. Do not append `/v1` twice.
</Warning>

## 2. Authenticate [#2-authenticate]

### Today: `X-API-Key` [#today-x-api-key]

Send a Journey API key in the `X-API-Key` header:

```http
X-API-Key: jny_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

- Only **partner-level** and **admin-level** keys are accepted. A service-level
  key is rejected with `403`.
- A revoked or expired key returns `401`.
- `X-API-Key` is deliberately not in the CORS allow-list, so this method is
  **server to server only**. It will not work from a browser.

<Warning>
  Sending a `jny_` key as `Authorization: Bearer` returns
  `401 Invalid or expired token`. The Bearer scheme is for WorkOS access
  tokens, not API keys. Older examples showing `Bearer jny_…` are wrong.
</Warning>

### Also supported: WorkOS access tokens [#also-supported-workos-access-tokens]

`Authorization: Bearer <WorkOS JWT>` authenticates an operator's session, which
is how Journey's own surfaces call the API.

### Coming soon: WorkOS organization keys [#coming-soon-workos-organization-keys]

Organization-scoped WorkOS API keys are planned, with `Authorization: Bearer`
as the primary form and `X-API-Key` also accepted. They are **not accepted
yet** — build against `X-API-Key` today. See
[Partner authentication](/api-reference/partner/authentication).

## 3. Make your first call [#3-make-your-first-call]

`GET /v1/partner/scope` is the right first request: it tells you which
organization your credential belongs to and which venues it can reach, which
is what should drive everything else.

<CodeGroup>

```bash cURL
curl "https://api-stg.cf.journey.com/v1/partner/scope" \
  -H "X-API-Key: $JOURNEY_PARTNER_API_KEY"
```

```typescript TypeScript
const res = await fetch('https://api-stg.cf.journey.com/v1/partner/scope', {
  headers: { 'X-API-Key': process.env.JOURNEY_PARTNER_API_KEY! },
});

if (!res.ok) throw new Error(`Partner API ${res.status}`);
const scope = await res.json();
```

```python Python
import os, requests

res = requests.get(
    "https://api-stg.cf.journey.com/v1/partner/scope",
    headers={"X-API-Key": os.environ["JOURNEY_PARTNER_API_KEY"]},
    timeout=30,
)
res.raise_for_status()
scope = res.json()
```

</CodeGroup>

Then read some real data:

```bash cURL
curl "https://api-stg.cf.journey.com/v1/partner/reservations?limit=25" \
  -H "X-API-Key: $JOURNEY_PARTNER_API_KEY"
```

## 4. Understand what you got back [#4-understand-what-you-got-back]

A few conventions apply everywhere, and they are worth knowing before you write
any more code.

<ParamField header="X-API-Key" type="string" required>
  Your partner API key. Server to server only.
</ParamField>

<ParamField header="Idempotency-Key" type="string">
  Optional, and supported on every `POST`, `PUT`, `PATCH` and `DELETE` under
  `/partner`. Strongly recommended on writes.
</ParamField>

- **Scopes.** Each route requires one or more permissions. The reference shows
  them as pills on every endpoint. Where a controller and a handler each
  declare permissions, you need both.
- **Organization comes from your credential.** Partner callers cannot pass
  `?organizationId` — it is ignored.
- **404 means "not found, or not yours".** Out-of-scope resources are
  deliberately indistinguishable from ones that do not exist.
- **Responses are additive.** New fields appear over time; ignore any you do
  not recognise rather than failing on them.

## 5. Pick a pattern [#5-pick-a-pattern]

Most integrations are one of five shapes. Each guide has the call sequence and
the things that catch people out.

<CardGroup cols={2}>
  <Card title="Front-desk fulfillment" icon="concierge-bell" href="/guides/patterns/front-desk-fulfillment">
    Arrivals, verification codes and recording a benefit as delivered.
  </Card>
  <Card title="Roster sync" icon="refresh-cw" href="/guides/patterns/roster-sync">
    Reservations into your CRM or warehouse, with cursor pagination.
  </Card>
  <Card title="Program configuration" icon="settings-2" href="/guides/patterns/program-configuration">
    Programs, tiers, benefits and multipliers as code.
  </Card>
  <Card title="Guest invites" icon="mail" href="/guides/patterns/guest-invites">
    Get an unlinked stay credited to a member.
  </Card>
  <Card title="Code pools" icon="ticket" href="/guides/patterns/code-pools">
    Bulk promo-code inventory.
  </Card>
  <Card title="Errors and retries" icon="life-buoy" href="/guides/errors-idempotency-pagination">
    The conventions to build against before you scale up.
  </Card>
</CardGroup>
