> For the complete documentation index, see [llms.txt](https://docs.genlogs.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.genlogs.io/auth/create-token.md).

# Create token

### **Create Access Token**

The "Create Access Token" endpoint allows a user to generate new access and refresh tokens by providing their email and password. These tokens are essential for authenticating and authorizing API requests.

#### **Authentication**

* Include your **`x-api-key`** header with the API key provided by GenLogs. Requests without a valid key are rejected with **403 Forbidden**.

#### **Endpoint**

* **URL**: `https://api.genlogs.io/auth/token`
* **Method**: `POST`

#### **Request Parameters**

Send `email` and `password` in a JSON request body with the `Content-Type: application/json` header. No URL-encoding of special characters is needed (e.g. `1234+` can be sent as-is).

{% hint style="warning" %}
Query parameters are not supported. A request that sends `email` and `password` as query parameters instead of a JSON body is rejected with **400 Bad Request**.
{% endhint %}

Body schema:

```json
{ "email": "user@example.com", "password": "your_password" }
```

**Parameters**

* `email` (string, required): The email address of the user requesting the tokens. Must be a valid email address.
* `password` (string, required): The password of the user for authentication.

### **Request Example**

```sh
curl -X POST 'https://api.genlogs.io/auth/token' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'x-api-key: {your_api_key}' \
  -d '{
    "email": "{email}",
    "password": "{password}"
  }'
```

### **Response**

* **200 OK**: The access and refresh tokens were created and returned.
* **400 Bad Request**: The credentials were sent as query parameters, or `email` or `password` is missing from the body.
* **401 Unauthorized**: The email and password could not be validated, so no tokens were created.
* **403 Forbidden**: The `x-api-key` header is missing or invalid.
* **422 Unprocessable Entity**: The password is empty, the email is not a valid email address, or the body is not valid JSON.
* **429 Too Many Requests**: Too many token requests were made for the same account. Retry after the number of seconds in the `Retry-After` header.

### **Response Body**

{% hint style="info" %}
Note: The refresh token is not usable at this time. Please create a new token after your original access token has expired.
{% endhint %}

* **access\_token\_data** (TokenSchema): The schema representing the access token and its expiration.
  * **token** (string): The access token string used for authentication and authorization.
  * **expires** (datetime): The datetime when the access token expires.
* **refresh\_token\_data** (TokenSchema): The schema representing the refresh token and its expiration.
  * **token** (string): The refresh token string used to obtain a new access token.
  * **expires** (datetime): The datetime when the refresh token expires.
* **user\_id** (int): The ID of the user for whom the tokens were created.
* **company\_id** (int, nullable): The ID of the company associated with the authenticated user. May be `null`.
* **customer\_name** (string, nullable): The name of the customer associated with the authenticated user. May be `null`.

#### **Error Responses**

**400 Bad Request: credentials sent as query parameters**

The root key is `error`, not `detail`.

```json
{ "error": "Request body required as JSON. Query parameters are not supported for this endpoint." }
```

**400 Bad Request: `email` or `password` missing**

```json
{ "detail": "email and password are required" }
```

**401 Unauthorized**

The same message is returned for every authentication failure. The response includes an `X-Correlation-Id` header. **Include this value when contacting Support** so the failure can be traced.

```json
{ "detail": "Could not validate credentials" }
```

**403 Forbidden**

Returned by the API gateway before the request reaches the service when `x-api-key` is missing or invalid.

```json
{ "message": "Forbidden" }
```

**422 Unprocessable Entity: empty password**

`detail` is a string.

```json
{ "detail": "email and password cannot be empty" }
```

**422 Unprocessable Entity: invalid email, or body that is not valid JSON**

`detail` is an array of validation errors, each with `loc`, `msg`, and `type`.

```json
{
  "detail": [
    {
      "type": "value_error",
      "loc": ["body", "email"],
      "msg": "value is not a valid email address: An email address must have an @-sign.",
      "input": "not-an-email"
    }
  ]
}
```

**429 Too Many Requests**

Token requests are limited per IP address and account, and per account across all sources. The `Retry-After` response header gives the number of seconds to wait before retrying.

```json
{ "detail": "Too many requests. Please try again later." }
```

## Create access and refresh tokens

> Create and return new access and refresh tokens for a user based on their email and password. Credentials must be sent in the JSON request body. Query parameters are not supported: a request that sends credentials only as query parameters is rejected with HTTP 400.<br>

```json
{"openapi":"3.0.3","info":{"title":"Auth API - Create Token","version":"1.1.0"},"servers":[{"url":"https://api.genlogs.io","description":"GenLogs API"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key","description":"API key provided by GenLogs."}},"schemas":{"CreateTokenBody":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email","description":"Email of the user requesting tokens."},"password":{"type":"string","format":"password","description":"Password of the user requesting tokens."}}},"AuthSchema":{"type":"object","required":["access_token_data","refresh_token_data","user_id"],"properties":{"access_token_data":{"$ref":"#/components/schemas/TokenSchema"},"refresh_token_data":{"$ref":"#/components/schemas/TokenSchema"},"user_id":{"type":"integer"},"company_id":{"type":"integer","nullable":true},"customer_name":{"type":"string","nullable":true}}},"TokenSchema":{"type":"object","required":["token","expires"],"properties":{"token":{"type":"string"},"expires":{"type":"string","format":"date-time"}}},"QueryParamsNotSupportedError":{"type":"object","required":["error"],"properties":{"error":{"type":"string","enum":["Request body required as JSON. Query parameters are not supported for this endpoint."]}}},"DetailError":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}},"GatewayError":{"type":"object","properties":{"message":{"type":"string"}}},"HTTPValidationError":{"type":"object","required":["detail"],"properties":{"detail":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"}}}},"ValidationError":{"type":"object","required":["loc","msg","type"],"properties":{"loc":{"type":"array","items":{"oneOf":[{"type":"string"},{"type":"integer"}]}},"msg":{"type":"string"},"type":{"type":"string"},"input":{"description":"The value that failed validation."}}}}},"paths":{"/auth/token":{"post":{"tags":["auth"],"summary":"Create access and refresh tokens","description":"Create and return new access and refresh tokens for a user based on their email and password. Credentials must be sent in the JSON request body. Query parameters are not supported: a request that sends credentials only as query parameters is rejected with HTTP 400.\n","operationId":"createAccessToken","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTokenBody"}}}},"responses":{"200":{"description":"Access and refresh tokens created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthSchema"}}}},"400":{"description":"Bad Request. Returned when credentials are sent as query parameters instead of a JSON body (root key `error`), or when `email` or `password` is missing from the body (root key `detail`).\n","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/QueryParamsNotSupportedError"},{"$ref":"#/components/schemas/DetailError"}]}}}},"401":{"description":"Unauthorized. The credentials could not be validated. The same generic message is returned for every authentication failure. Include the `X-Correlation-Id` header value when contacting Support.\n","headers":{"X-Correlation-Id":{"description":"Unique id of the failed request. Provide it to Support.","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetailError"}}}},"403":{"description":"Forbidden. The `x-api-key` header is missing or invalid. Returned by the API gateway before the request reaches the service.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayError"}}}},"422":{"description":"Unprocessable Entity. `detail` is a string when the password is an empty string, and an array of validation errors when the body is not valid JSON or `email` is not a valid email address (including an empty string).\n","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/DetailError"},{"$ref":"#/components/schemas/HTTPValidationError"}]}}}},"429":{"description":"Too Many Requests. Login attempts are limited per IP and account, and per account across all sources. Wait the number of seconds in `Retry-After` before retrying.\n","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetailError"}}}}}}}}}
```
