# API authentication
Authenticate protected Plandalf API requests, confirm the active user, and understand which organization the API will use.
Source: /docs/api/authentication
Last modified: 2026-06-20
## API reference
- Method: `GET`
- Path: `/api/users/me`
- Request URL: `https://api.plandalf.com/api/users/me`
- Authentication: `Bearer token`
- Playground: `simple`
- Operation ID: `getCurrentUser`
Authentication has one job: prove who is making the request before you read or change commerce data. Start by checking identity, then make the smallest real API call from your server.


> **Do this before any catalog, checkout, or automation call**
>

  Make `GET /api/users/me` work first. It tells you whether the token is valid and which organization Plandalf will use for organization-scoped records.


## The path


### Store the token on your server


    Keep API credentials in environment variables, server secrets, or your platform's secret manager. Do not put them in JavaScript that ships to the browser.


### Send it as a bearer header


    Every protected API request should include `Authorization: Bearer <token>` and `Accept: application/json`.


### Check the active identity


    Call `GET /api/users/me` before moving on. If this fails, the next API page will fail too.


### Use the resolved organization


    The response includes `current_organization`. Catalog, checkout, and automation routes use that context for organization-owned data.


## Identity endpoint

Use this as the first server-side smoke test. It proves the bearer token works and shows the organization context later API calls will inherit.

<ApiEndpoint
  id="identity-endpoint"
  method="GET"
  path="/api/users/me"
  title="Get current user"
  description="Returns the authenticated user and current organization context for protected API calls."
  auth="Bearer token"
  availability="Protected API"
  operationId="getCurrentUser"
>


### Headers


- `Authorization` (string; required):
    Send `Bearer <token>`. Requests without a valid bearer credential cannot resolve the authenticated user or current organization.


- `Accept` (string; default: application/json):
    Ask API routes to return JSON.


- `Content-Type` (string; default: application/json):
    Include this when the request sends a JSON body.


### Identity request


```bash title="GET /api/users/me"
curl "https://api.plandalf.com/api/users/me" \
  -H "Authorization: Bearer $PLANDALF_API_KEY" \
  -H "Accept: application/json"
```

```js title="get-current-user.js"
const response = await fetch("https://api.plandalf.com/api/users/me", {
  headers: {
    Authorization: `Bearer ${process.env.PLANDALF_API_KEY}`,
    Accept: "application/json",
  },
});

if (!response.ok) {
  throw new Error(`Plandalf authentication failed: ${response.status}`);
}

const identity = await response.json();
```


### Identity response

The identity check is not just a ping. It shows the user and organization context that later API calls will inherit. Keep the first read small: confirm the user, confirm `current_organization`, then move on.


### Identity response


```json title="200 identity response"
{
  "id": "usr_123",
  "email": "founder@example.com",
  "current_organization": {
    "id": "org_123",
    "name": "Example Studio",
    "timezone": "Australia/Sydney"
  }
}
```


### Invalid token


```json title="401 unauthorized"
{
  "message": "Unauthenticated."
}
```


### Response fields


- `id` (string):
    The authenticated user's route key.


- `email` (string):
    The email address for the authenticated Plandalf user.


- `plandalf_jwt` (string):
    A signed Plandalf JWT for browser or embedded surfaces that need to identify the current user. Treat it as sensitive.


- `current_organization` (object; required):
    The organization currently selected for the authenticated user. Organization-scoped API routes use this context.


- `current_organization.id` (string):
      The organization route key.


- `current_organization.name` (string):
      The name shown inside Plandalf.


- `current_organization.timezone` (string):
      The timezone used for organization display and date handling.


- `organizations` (array):
    Other organizations available to the authenticated user.


### Error fields


- `message` (string):
    Authentication failure message returned when the bearer token is missing, expired, or invalid.


</ApiEndpoint>

## Where credentials belong


### Credential placement


- `Server routes` (private):
    Best for catalog reads, checkout session creation, automation setup, and anything that touches private records.


- `Browser checkout` (public):
    Use the checkout SDK for browser behavior. Do not expose API bearer credentials in front-end code.


> **Do not rely on URL tokens**
>

  If an older integration depends on URL-based authentication, treat it as compatibility behavior and move it behind the `Authorization` header before going live.


## Next calls

- [Catalog API](/docs/api/catalog): read products and plans after the token resolves the right organization.
- [Checkout SDK](/docs/api/sdk-checkout): pair server-side API calls with client-side checkout behavior.
- [Webhooks](/docs/api/webhooks): fan external events into Plandalf workflows.