Auth
Exchange an API key for a short-lived access token. This step is optional: the API also accepts the API key directly as a Bearer token.
POST
/oauth/tokenExchange an API key for a JWT that is valid for 60 minutes and carries the client's scopes, using the OAuth 2.0 client_credentials grant. Send the API client ID as client_id and the API key (zk_live_… or zk_test_…) as client_secret, in either application/x-www-form-urlencoded (RFC 6749) or application/json. This step is optional: the API also accepts the API key directly as a Bearer token.
Request body application/x-www-form-urlencoded
Responses
200The issued access token.
Headers: X-Request-Id
400The request is malformed.
401The API key or token is missing, invalid, expired or revoked. The code is unauthorized, key_expired or key_revoked.
Headers: X-Request-Id
403The credential is valid but is not allowed to make this request. The code is scope_missing, plan_required, ip_not_allowed or client_suspended.
429The rate limit was exceeded. Retry after the number of seconds given in Retry-After.
Headers: Retry-After RateLimit-Limit RateLimit-Remaining RateLimit-Reset
curl -X POST "https://sandbox-api.zester.co.il/v2https://api.zester.co.il/v2/oauth/token" \
-d "grant_type=client_credentials" \
-d "client_id=cl_01J9KQ7X4M" \
-d "client_secret=zk_test_XXXXXXXX_…zk_live_XXXXXXXX_…" \
-d "scope=supplier.orders:read supplier.orders:write supplier.documents:write"const res = await fetch("https://sandbox-api.zester.co.il/v2https://api.zester.co.il/v2/oauth/token", {
method: "POST",
headers: {
},
body: new URLSearchParams({
grant_type: "client_credentials",
client_id: "cl_01J9KQ7X4M",
client_secret: "zk_test_XXXXXXXX_…zk_live_XXXXXXXX_…",
scope: "supplier.orders:read supplier.orders:write supplier.documents:write",
}),
});
const data = await res.json();import requests
res = requests.post(
"https://sandbox-api.zester.co.il/v2https://api.zester.co.il/v2/oauth/token",
data={
"grant_type": "client_credentials",
"client_id": "cl_01J9KQ7X4M",
"client_secret": "zk_test_XXXXXXXX_…zk_live_XXXXXXXX_…",
"scope": "supplier.orders:read supplier.orders:write supplier.documents:write",
},
)
data = res.json()using var http = new HttpClient();
var body = new FormUrlEncodedContent(new Dictionary<string, string>
{
["grant_type"] = "client_credentials",
["client_id"] = "cl_01J9KQ7X4M",
["client_secret"] = "zk_test_XXXXXXXX_…zk_live_XXXXXXXX_…",
["scope"] = "supplier.orders:read supplier.orders:write supplier.documents:write",
});
var res = await http.PostAsync("https://sandbox-api.zester.co.il/v2https://api.zester.co.il/v2/oauth/token", body);
var data = await res.Content.ReadAsStringAsync();
{
"access_token": "eyJhbGciOiJSUzI1NiJ9.XXXXXXXX",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "supplier.orders:read supplier.orders:write supplier.documents:write"
}{
"type": "https://developers.zester.co.il/errors/validation_error",
"title": "Malformed request",
"status": 400,
"code": "validation_error",
"detail": "grant_type \"password\" is not supported. API v2 accepts only client_credentials.",
"instance": "/v2/oauth/token",
"request_id": "req_01J9KQ8A2C",
"errors": [
{
"field": "grant_type",
"code": "unsupported_value",
"message": "Use client_credentials"
}
]
}{
"type": "https://developers.zester.co.il/errors/unauthorized",
"title": "Invalid client credentials",
"status": 401,
"code": "unauthorized",
"detail": "client_secret is not a valid key for client cl_01J9KQ7X4M.",
"instance": "/v2/oauth/token",
"request_id": "req_01J9KQ8B5D"
}{
"type": "https://developers.zester.co.il/errors/ip_not_allowed",
"title": "IP address not allowed",
"status": 403,
"code": "ip_not_allowed",
"detail": "Requests from 198.51.100.23 are not in the IP allowlist of client cl_01J9KQ7X4M.",
"instance": "/v2/oauth/token",
"request_id": "req_01J9KQ8C7F"
}{
"type": "https://developers.zester.co.il/errors/rate_limited",
"title": "Too many requests",
"status": 429,
"code": "rate_limited",
"detail": "Client cl_01J9KQ7X4M requested 30 tokens in the last minute. Reuse the current token until it expires (60 minutes).",
"instance": "/v2/oauth/token",
"request_id": "req_01J9KQ8D3G"
}