> This page is for Entria API Reference.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.navipartner.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.navipartner.com/_mcp/server.

# Email a login code

POST https://api.entria.app/api/account/login
Content-Type: application/json

Starts a login for any email address: the email is the shopper’s account, and Business Central memberships attach to it when there are any. A 6-digit code is emailed to the address; exchange it at `POST /api/account/session`. The answer is always `202`, so it says nothing about the address. A code is valid for 10 minutes from the first request and allows 5 attempts; asking again inside that window sends a new code (at most once a minute) but does not extend it or reset the attempts. At most 10 codes are sent to one inbox in 24 hours. These limits count per inbox, not per spelling: `+tag` sub-addresses, and dots in a Gmail address, share their inbox’s limits.

Reference: https://docs.navipartner.com/entria-api/entria-api-reference/account/post-member-login

## Request

### Headers

- `x-entria` (string, required) — Identifies which store this request is for. Required on every store-scoped route. It is not authentication and not a secret — it grants no privileges and is safe to send from a browser. You receive the value once your Entria backend has been created and configured. Missing header returns 400; an unknown store returns 404.

### Body (application/json)

This endpoint expects an object.

- `email` (string, required) — The shopper’s email address.
- `locale` (string, optional) — BCP 47 locale for the email (e.g. da-DK). Defaults to the store’s.

## Response

### 202

Accepted. A code is emailed unless its inbox is cooling down, locked or over its daily limit, the store is over its login send budget, or the mail cannot be sent (for example, the store has no login template).

- `status` (enum, required)
  - Allowed values: `accepted`

## Errors

### 400 Bad Request Error

The request body is invalid.

- `error` (string, required)
- `code` (string, optional)
- `details` (list of ErrorResponseDetailsItems, optional) — Per-field validation failures; present when code is VALIDATION_ERROR.
- `success` (boolean, optional, deprecated) — Deprecated. Use code === VALIDATION_ERROR.
- `errors` (list of any, optional, deprecated) — Deprecated. Raw zod issues; use details instead.

### 404 Not Found Error

Email login ("Email Login" in the store’s checkout settings) is not enabled for this store (`code: ACCOUNT_LOGIN_DISABLED`), or the `x-entria` store handle is unknown.

- `error` (string, required)
- `code` (string, optional)
- `details` (list of ErrorResponseDetailsItems, optional) — Per-field validation failures; present when code is VALIDATION_ERROR.
- `success` (boolean, optional, deprecated) — Deprecated. Use code === VALIDATION_ERROR.
- `errors` (list of any, optional, deprecated) — Deprecated. Raw zod issues; use details instead.

### 429 Too Many Requests Error

Too many requests from this client.

- `error` (string, required)
- `code` (string, optional)
- `details` (list of ErrorResponseDetailsItems, optional) — Per-field validation failures; present when code is VALIDATION_ERROR.
- `success` (boolean, optional, deprecated) — Deprecated. Use code === VALIDATION_ERROR.
- `errors` (list of any, optional, deprecated) — Deprecated. Raw zod issues; use details instead.

### 503 Service Unavailable Error

Email login is switched on but cannot run: Business Central is not configured for the store (`code: BC_NOT_CONFIGURED`), or this service is missing its token configuration (`code: ACCOUNT_LOGIN_NOT_CONFIGURED`). Neither depends on the email.

- `error` (string, required)
- `code` (string, optional)
- `details` (list of ErrorResponseDetailsItems, optional) — Per-field validation failures; present when code is VALIDATION_ERROR.
- `success` (boolean, optional, deprecated) — Deprecated. Use code === VALIDATION_ERROR.
- `errors` (list of any, optional, deprecated) — Deprecated. Raw zod issues; use details instead.

## Types

### ErrorResponseDetailsItems

- `path` (string, required)
- `message` (string, required)

## Examples

**Request**

```json
{
  "email": "string"
}
```

**Response**

```json
{
  "status": "accepted"
}
```

**SDK Code**

```python
import requests

url = "https://api.entria.app/api/account/login"

payload = { "email": "string" }
headers = {
    "x-entria": "x-entria",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.entria.app/api/account/login';
const options = {
  method: 'POST',
  headers: {'x-entria': 'x-entria', 'Content-Type': 'application/json'},
  body: '{"email":"string"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.entria.app/api/account/login"

	payload := strings.NewReader("{\n  \"email\": \"string\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("x-entria", "x-entria")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.entria.app/api/account/login")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["x-entria"] = 'x-entria'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"email\": \"string\"\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.entria.app/api/account/login")
  .header("x-entria", "x-entria")
  .header("Content-Type", "application/json")
  .body("{\n  \"email\": \"string\"\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.entria.app/api/account/login', [
  'body' => '{
  "email": "string"
}',
  'headers' => [
    'Content-Type' => 'application/json',
    'x-entria' => 'x-entria',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.entria.app/api/account/login");
var request = new RestRequest(Method.POST);
request.AddHeader("x-entria", "x-entria");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"email\": \"string\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "x-entria": "x-entria",
  "Content-Type": "application/json"
]
let parameters = ["email": "string"] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.entria.app/api/account/login")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```