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

# Authenticate Users with the Squire Token API

> Request short-lived access tokens from your backend using your Squire API key, then pass them to the SDK to initialize per-user sessions in your EHR.

Before you can use the Squire SDK or Widget, each user session needs a valid access token. You request this token from your backend using your Squire API key, then pass it to the frontend to initialize the SDK. If you don't have an API key yet, [create one in the Portal](/portal#managing-api-keys).

<Warning>
  Never make token requests from the client side. Your API key must remain secret and must only be used in your backend server environment.
</Warning>

## Authentication flow

The token-based flow keeps your API key secure on the server while giving the frontend the short-lived credential it needs.

<Steps>
  <Step title="Frontend requests a token">
    Your EHR frontend calls an endpoint on your own backend to request an access token for the current user.
  </Step>

  <Step title="Backend calls the Squire API">
    Your backend sends a POST request to `https://api.squire.eu/api/v1/token/` with your API key and the user's details.
  </Step>

  <Step title="Squire validates and responds">
    The Squire API validates your API key and the user data, then returns a signed access token and its expiration timestamp.
  </Step>

  <Step title="Backend returns the token">
    Your backend passes the token back to the frontend — never the API key.
  </Step>

  <Step title="Frontend initializes the SDK">
    Your EHR frontend uses the access token to initialize the Squire SDK for that user's session.
  </Step>
</Steps>

## Request an access token

Send a POST request to the token endpoint from your server. All requests must include your API key in the `X-Api-Key` header.

<Note>
  Token requests must be made server-side only. The API key used to authenticate this request is a private secret and must never appear in client-side code.
</Note>

**Endpoint:** `POST https://api.squire.eu/api/v1/token/`

### Request headers

<ParamField header="X-Api-Key" type="string" required>
  Your Squire API key for authentication. Generate this from the [Squire Portal](https://app.squire.eu).
</ParamField>

<ParamField header="Content-Type" type="string" required>
  Must be set to `application/json`.
</ParamField>

### Request body parameters

<ParamField body="user_id" type="string" required>
  The unique identifier for this user in your system. This ties the Squire session to a specific user in your EHR.
</ParamField>

<ParamField body="first_name" type="string" required>
  First name of the user.
</ParamField>

<ParamField body="last_name" type="string" required>
  Last name of the user.
</ParamField>

<ParamField body="organisation" type="string" required>
  The name of the organisation where the user works — for example, the practice, clinic, or hospital name.
</ParamField>

<ParamField body="healthcare_provider_identification_number" type="string">
  The official identification number for this healthcare provider — for example, a RIZIV number in Belgium. Separators between characters are allowed.
</ParamField>

<ParamField body="email" type="string">
  Email address of the user in your system.
</ParamField>

<ParamField body="healthcare_provider_type" type="string">
  The type of healthcare provider. Use the ID values from the table below. Providing this value improves the accuracy of generated consultation reports.
</ParamField>

### Healthcare provider type IDs

Use one of the following `id` values for the `healthcare_provider_type` parameter:

| Name                        | ID                            |
| --------------------------- | ----------------------------- |
| Anesthesiologist            | `anesthesiologist`            |
| Cardiologist                | `cardiologist`                |
| Dermatologist               | `dermatologist`               |
| Dietitian                   | `dietitian`                   |
| Emergency Doctor            | `emergency_doctor`            |
| Endocrinologist             | `endocrinologist`             |
| Gastroenterologist          | `gastroenterologist`          |
| General Practitioner        | `general_practitioner`        |
| Geriatrician                | `geriatrician`                |
| Gynecologist                | `gynecologist`                |
| Hematologist                | `hematologist`                |
| Home Nurse                  | `home_nurse`                  |
| Hospital Nurse              | `hospital_nurse`              |
| Infectiologist              | `infectiologist`              |
| Nephrologist                | `nephrologist`                |
| Neurologist                 | `neurologist`                 |
| Nursing Home Nurse          | `nursing_home_nurse`          |
| Oncologist                  | `oncologist`                  |
| Ophthalmologist             | `ophthalmologist`             |
| Orthopedic                  | `orthopedic`                  |
| Otorhinolaryngologist       | `otorhinolaryngologist`       |
| Pediatrician                | `pediatrician`                |
| Physiotherapist             | `physiotherapist`             |
| Practice Nurse              | `practice_nurse`              |
| Psychiatrist                | `psychiatrist`                |
| Psychologist                | `psychologist`                |
| Pulmonologist               | `pulmonologist`               |
| Radiologist                 | `radiologist`                 |
| Rheumatologist              | `rheumatologist`              |
| Surgeon                     | `surgeon`                     |
| Speech-Language Pathologist | `speech_language_pathologist` |
| Stomatologist               | `stomatologist`               |
| Urologist                   | `urologist`                   |

### Code examples

The following examples show how to request a token from your backend server. Replace `YOUR_API_KEY` with the key from your Portal.

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST "https://api.squire.eu/api/v1/token/" \
    -H "X-Api-Key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "user_id": "doctor123",
      "first_name": "doctor",
      "last_name": "123",
      "organisation": "practice_name",
      "healthcare_provider_identification_number": "12345678901",
      "email": "doctor@123.com",
      "healthcare_provider_type": "general_practitioner"
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.squire.eu/api/v1/token/', {
    method: 'POST',
    headers: {
      'X-Api-Key': 'YOUR_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      user_id: 'doctor@example.com',
      first_name: 'doctor',
      last_name: '123',
      organisation: 'practice_name',
      healthcare_provider_identification_number: '12345678901',
      email: 'doctor@123.com',
      healthcare_provider_type: 'general_practitioner',
    }),
  });

  const data = await response.json();
  const accessToken = data.token;
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'https://api.squire.eu/api/v1/token/',
      headers={'X-Api-Key': 'YOUR_API_KEY'},
      json={
          'user_id': 'doctor@example.com',
          'first_name': 'doctor',
          'last_name': '123',
          'organisation': 'practice_name',
          'healthcare_provider_identification_number': '12345678901',
          'email': 'doctor@123.com',
          'healthcare_provider_type': 'general_practitioner',
      },
  )

  access_token = response.json()['token']
  ```

  ```csharp C# (.NET) theme={null}
  using System.Net.Http;
  using System.Text.Json;

  var client = new HttpClient();
  client.DefaultRequestHeaders.Add("X-Api-Key", "YOUR_API_KEY");

  var payload = new
  {
      user_id = "doctor@example.com",
      first_name = "doctor",
      last_name = "123",
      organisation = "practice_name",
      healthcare_provider_identification_number = "12345678901",
      email = "doctor@123.com",
      healthcare_provider_type = "general_practitioner",
  };

  var content = new StringContent(
      JsonSerializer.Serialize(payload),
      System.Text.Encoding.UTF8,
      "application/json"
  );

  var response = await client.PostAsync("https://api.squire.eu/api/v1/token/", content);
  var result = await response.Content.ReadAsStringAsync();
  var data = JsonSerializer.Deserialize<JsonDocument>(result);
  var accessToken = data.RootElement.GetProperty("token").GetString();
  ```

  ```java Java theme={null}
  import java.net.http.HttpClient;
  import java.net.http.HttpRequest;
  import java.net.http.HttpResponse;
  import java.net.URI;
  import javax.json.Json;
  import javax.json.JsonObject;
  import javax.json.JsonReader;
  import java.io.StringReader;

  HttpClient client = HttpClient.newHttpClient();
  HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://api.squire.eu/api/v1/token/"))
      .header("X-Api-Key", "YOUR_API_KEY")
      .header("Content-Type", "application/json")
      .POST(HttpRequest.BodyPublishers.ofString(
          "{\"user_id\": \"doctor@example.com\", \"first_name\": \"doctor\", " +
          "\"last_name\": \"123\", \"organisation\": \"practice_name\", " +
          "\"healthcare_provider_identification_number\": \"12345678901\", " +
          "\"email\": \"doctor@123.com\", " +
          "\"healthcare_provider_type\": \"general_practitioner\"}"
      ))
      .build();

  HttpResponse<String> response = client.send(
      request,
      HttpResponse.BodyHandlers.ofString()
  );

  JsonReader jsonReader = Json.createReader(new StringReader(response.body()));
  JsonObject jsonObject = jsonReader.readObject();
  String accessToken = jsonObject.getString("token");
  jsonReader.close();
  ```
</CodeGroup>

## Response

### 200 Successful response

A successful request returns an access token and its expiration timestamp. Pass the `token` value to the Squire SDK on your frontend.

```json theme={null}
{
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "expires_at": "2025-01-01T14:30:00Z"
}
```

<ResponseField name="token" type="string" required>
  A signed JWT access token. Pass this to the Squire SDK to initialize a user session.
</ResponseField>

<ResponseField name="expires_at" type="string" required>
  The token's expiration time in ISO 8601 format. Request a new token before this time to keep sessions active.
</ResponseField>

### Error responses

#### 400 Bad request

Returned when the request is missing required parameters or contains invalid values. The response body is a list of validation errors.

```json theme={null}
[
  {
    "loc": ["organisation"],
    "msg": "Field required",
    "type": "missing"
  }
]
```

Check the `loc` field in each error object to identify which parameter needs to be corrected.

#### 401 Unauthorized

Returned when the API key is invalid or missing from the request headers.

```json theme={null}
{
  "error": "Invalid API key provided"
}
```

<ResponseField name="error" type="string">
  A human-readable description of what went wrong.
</ResponseField>

Verify that your `X-Api-Key` header is present and matches a valid key from your Portal.

#### 403 Forbidden

Returned when the user context in the request body is invalid or unauthorized.

```json theme={null}
{
  "error": "Invalid user_id provided"
}
```

<ResponseField name="error" type="string">
  A human-readable description of what went wrong.
</ResponseField>

#### 429 Too many requests

Returned when your backend exceeds the API rate limit. Wait for the number of seconds specified in `retry_after` before sending another request.

```json theme={null}
{
  "error": "Rate limit exceeded",
  "retry_after": 60
}
```

<ResponseField name="error" type="string">
  A human-readable description of what went wrong.
</ResponseField>

<ResponseField name="retry_after" type="number">
  The number of seconds to wait before retrying the request.
</ResponseField>

## Next steps

Now that you have a valid access token, continue with your chosen integration path:

<CardGroup cols={2}>
  <Card title="SDK installation" icon="code" href="/integration/sdk/installation">
    Install the Squire JavaScript SDK and initialize it with your access token.
  </Card>

  <Card title="Widget installation" icon="window" href="/integration/widgets/introduction">
    Embed the pre-built Squire Widget using your access token.
  </Card>
</CardGroup>
