# Authentication Building with an AI agent? Start at https://docs.payme.io/agents.md The Products & Customers API hosts (sandbox and production), how to get and refresh the access token its calls need, and the shape of its error responses. ## Related - [Get an access token](/products-and-customers/authentication/post-auth-token) - [Refresh an access token](/products-and-customers/authentication/post-auth-refresh) - [Authentication](/payments/getting-started/authentication) Products & Customers keeps a seller's product catalogue and customer list. It is a separate PayMe service with its own access token: get a token for the seller, then send it as `Authorization: Bearer ` on every product and customer call. ## Hosts | Environment | Base URL | |---|---| | Sandbox (testing) | `https://payme-store-staging.payme.io/api/` | | Production | `https://payme-store.payme.io/api/` | These hosts are separate from the Payments API hosts (`sandbox.payme.io`, `live.payme.io`). Use sandbox credentials (the seller's sandbox MPL and your sandbox `payme_client_key`) with the sandbox host, and production credentials with the production host. ## Authentication 1. Call [`POST /auth-tokens`](/products-and-customers/authentication/post-auth-token) with `{"mpl": "", "key": ""}`. The seller must belong to the partner whose key you send. The call returns HTTP `201` with `auth_token` (a JWT) and `refresh_token`. 2. Send `Authorization: Bearer ` on every product and customer call. A missing, invalid or expired token returns HTTP `401`. 3. When the access token expires, call [`POST /refresh-exchanges`](/products-and-customers/authentication/post-auth-refresh) with `{"refresh_token": ""}`. No headers are needed. It returns a new `auth_token` and a new `refresh_token`. Each refresh token works once, so store the new one. If the refresh token has expired or was already used, start again at step 1. Only partners can get a token: `key` is the partner's `payme_client_key`, and a seller without a partner key can't call this API. What the MPL (`seller_payme_id`) and the partner key are: Payments [Authentication](/payments/getting-started/authentication). ## Amounts Prices in this API are decimal amounts in major units, sent as money objects such as `{"amount": 99.99, "currency": "ILS"}`. This differs from the Payments API, which uses minor units. ## Errors Every error returns a JSON body with these fields: | Field | Type | Description | |---|---|---| | `status_error_details` | string | What went wrong. Validation messages are in Hebrew unless you send `Accept-Language: en` (or add `?lang=en`). | | `status_error_code` | integer | `501` – a field failed validation (HTTP `400`). `999` – any other error. | | `validation_errors` | object | Validation errors only. Each key is a field name; its value maps each failed rule to a message. | | `status_additional_info` | string | Extra detail, when there is any. | | `session` | string | Trace id of the request. Quote it when you contact PayMe support. | | HTTP status | Meaning | |---|---| | `400` | Invalid input: a missing or invalid field, a body that isn't valid JSON, or a `guid` that isn't a UUID. | | `401` | Missing, invalid or expired access token, or a refresh token that is unknown, used or expired. | | `404` | The product or customer doesn't exist, was deleted, or belongs to another seller. | | `409` | Another of the seller's products already uses that `product_remote_id`, or another customer that `customer_external_id`. | | `500` | Server error. Contact PayMe support and quote the `session`. | ```json { "status_error_details": "Field validation failed.", "validation_errors": { "items_per_page": { "max": "The value must be less than max amount." } }, "status_error_code": 501, "session": "f3a1c2b0-9e4d-11ef-8c1a-0242ac120002" } ``` ## Endpoints - [Get an access token](/products-and-customers/authentication/post-auth-token): POST /auth-tokens - [Refresh an access token](/products-and-customers/authentication/post-auth-refresh): POST /refresh-exchanges