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

# Quickstart

> From API key to your first member in five minutes

This page gets you from zero to a successful authenticated call against the
4D nonprod environment.

## 1. Get your API key

Your organization's admin obtains an API key during partner onboarding (or
from the 4D team directly). Keys are prefixed `org_` and are scoped to your
organization - every call you make operates inside your own tenant, enforced
at the database layer.

<Warning>
  The `org_` key is a server-side secret. Never ship it in client code - for
  browser event tracking there is a separate publishable key type, covered in
  [Trigger an event](/walkthroughs/trigger-an-event).
</Warning>

## 2. Set up your environment

All examples in these docs target the nonprod environment:

```bash theme={null}
export API_BASE_URL="https://api.develop.fourdos.dev"
export API_KEY="org_…your key…"
```

## 3. Make your first call

Create (or attach) a member of your organization:

```bash theme={null}
curl -X POST "$API_BASE_URL/v1/users" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: quickstart-001" \
  -d '{
    "email": "ada.lovelace@example.com",
    "external_id": "cust-001",
    "display_name": "Ada L."
  }'
```

A `201 Created` comes back with the full user record:

```json theme={null}
{
  "id": "0198f2b1-…",
  "email": "ada.lovelace@example.com",
  "display_name": "Ada L.",
  "status": "active",
  "wallet": { "status": "provisioning", "address": null },
  "membership": {
    "id": "…",
    "external_id": "cust-001",
    "role": "member",
    "status": "active",
    "joined_at": "2026-07-17T00:00:00.000Z"
  }
}
```

Run the same command again - same `Idempotency-Key`, same body - and you get
the same user back with a `200` instead of a duplicate. Retries are safe by
design.

## Conventions to know

* **Wire format** - JSON, `snake_case` field names.
* **Errors** - every error shares one envelope:
  ```json theme={null}
  { "error": { "code": "VALIDATION_ERROR", "status": 422, "message": "…", "details": { } } }
  ```
  `code` is the stable contract; `message` wording may change.
* **Idempotency** - mutating endpoints that declare it accept an
  `Idempotency-Key` header. Replaying the same key with the same body returns
  the original response; the same key with a different body is rejected with
  `409 IDEMPOTENCY_CONFLICT`.

## Next steps

<CardGroup cols={2}>
  <Card title="Authentication" icon="key" href="/authentication">
    The three credential types and when each applies.
  </Card>

  <Card title="Walkthrough: create a user" icon="user-plus" href="/walkthroughs/create-a-user">
    The full lifecycle: create, fetch, update, lock, remove.
  </Card>
</CardGroup>
