auth
Obtenir un bearer court
Echange une cle API brute contre un bearer MARKO court. La signature HMAC-SHA256 est calculee avec la cle API brute sur le message canonique MARKO-EXTERNAL-API-TOKEN-V1\n{key_id}\n{timestamp}\n{nonce}. Utilisez ensuite Authorization: Bearer YOUR_BEARER_HERE sur les endpoints metier.
cURL + OpenSSL
api_key="YOUR_API_KEY"
key_id="YOUR_PUBLIC_KEY_ID"
timestamp="$(date +%s)"
nonce="$(openssl rand -hex 16)"
message="$(printf 'MARKO-EXTERNAL-API-TOKEN-V1\n%s\n%s\n%s' "$key_id" "$timestamp" "$nonce")"
signature="$(printf "%s" "$message" | openssl dgst -sha256 -hmac "$api_key" -hex | awk '{print $2}')"
curl -X POST "https://partner-api.marko.fr/v1/auth/token" \
-H "Content-Type: application/json" \
-H "X-Request-ID: marko-auth-token" \
--data "$(printf '{"key_id":"%s","timestamp":%s,"nonce":"%s","signature":"%s"}' "$key_id" "$timestamp" "$nonce" "$signature")"import hashlib
import hmac
import secrets
import time
import requests
api_key = "YOUR_API_KEY"
key_id = "YOUR_PUBLIC_KEY_ID"
timestamp = int(time.time())
nonce = secrets.token_urlsafe(24)
message = f"MARKO-EXTERNAL-API-TOKEN-V1\n{key_id}\n{timestamp}\n{nonce}"
signature = hmac.new(api_key.encode(), message.encode(), hashlib.sha256).hexdigest()
resp = requests.post(
"https://partner-api.marko.fr/v1/auth/token",
headers={"X-Request-ID": "marko-auth-token"},
json={
"key_id": key_id,
"timestamp": timestamp,
"nonce": nonce,
"signature": signature,
},
timeout=30,
)
resp.raise_for_status()
access_token = resp.json()["access_token"]import { createHmac, randomBytes } from "node:crypto"
const apiKey = "YOUR_API_KEY"
const keyId = "YOUR_PUBLIC_KEY_ID"
const timestamp = Math.floor(Date.now() / 1000)
const nonce = randomBytes(24).toString("base64url")
const message = `MARKO-EXTERNAL-API-TOKEN-V1\n${keyId}\n${timestamp}\n${nonce}`
const signature = createHmac("sha256", apiKey).update(message).digest("hex")
const response = await fetch("https://partner-api.marko.fr/v1/auth/token", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Request-ID": "marko-auth-token",
},
body: JSON.stringify({
key_id: keyId,
timestamp,
nonce,
signature,
}),
})
const { access_token: accessToken } = await response.json(){
"access_token": "YOUR_BEARER_HERE",
"token_type": "Bearer",
"expires_in": 900,
"issued_at": "2026-04-23T10:00:00Z",
"expires_at": "2026-04-23T10:15:00Z",
"key_id": "YOUR_PUBLIC_KEY_ID",
"environment": "live",
"entity_slug": "clubfunding"
}{
"type": "about:blank",
"title": "Unauthorized",
"status": 401,
"detail": "A valid bearer token is required.",
"request_id": "req_example_partner_call"
}{
"type": "about:blank",
"title": "Forbidden",
"status": 403,
"detail": "The API key does not allow this operation.",
"request_id": "req_example_partner_call"
}{
"type": "about:blank",
"title": "Unprocessable Content",
"status": 422,
"detail": "The request payload or parameters are invalid.",
"request_id": "req_example_partner_call"
}{
"type": "about:blank",
"title": "Too Many Requests",
"status": 429,
"detail": "The request rate limit was exceeded.",
"request_id": "req_example_partner_call"
}{
"type": "about:blank",
"title": "Internal Server Error",
"status": 500,
"detail": "An unexpected server error occurred.",
"request_id": "req_example_partner_call"
}Headers
Partner-generated correlation identifier echoed in logs and error payloads.
Body
application/json
Public identifier of the API key generated from the MARKO entity admin API section.
Unix timestamp in seconds. Requests outside the accepted clock skew are rejected.
Unique random value. Reusing a nonce for the same key is rejected.
HMAC-SHA256 hex digest of the canonical exchange message.
Pattern:
^[A-Fa-f0-9]{64}$Response
Successful response
⌘I
cURL + OpenSSL
api_key="YOUR_API_KEY"
key_id="YOUR_PUBLIC_KEY_ID"
timestamp="$(date +%s)"
nonce="$(openssl rand -hex 16)"
message="$(printf 'MARKO-EXTERNAL-API-TOKEN-V1\n%s\n%s\n%s' "$key_id" "$timestamp" "$nonce")"
signature="$(printf "%s" "$message" | openssl dgst -sha256 -hmac "$api_key" -hex | awk '{print $2}')"
curl -X POST "https://partner-api.marko.fr/v1/auth/token" \
-H "Content-Type: application/json" \
-H "X-Request-ID: marko-auth-token" \
--data "$(printf '{"key_id":"%s","timestamp":%s,"nonce":"%s","signature":"%s"}' "$key_id" "$timestamp" "$nonce" "$signature")"import hashlib
import hmac
import secrets
import time
import requests
api_key = "YOUR_API_KEY"
key_id = "YOUR_PUBLIC_KEY_ID"
timestamp = int(time.time())
nonce = secrets.token_urlsafe(24)
message = f"MARKO-EXTERNAL-API-TOKEN-V1\n{key_id}\n{timestamp}\n{nonce}"
signature = hmac.new(api_key.encode(), message.encode(), hashlib.sha256).hexdigest()
resp = requests.post(
"https://partner-api.marko.fr/v1/auth/token",
headers={"X-Request-ID": "marko-auth-token"},
json={
"key_id": key_id,
"timestamp": timestamp,
"nonce": nonce,
"signature": signature,
},
timeout=30,
)
resp.raise_for_status()
access_token = resp.json()["access_token"]import { createHmac, randomBytes } from "node:crypto"
const apiKey = "YOUR_API_KEY"
const keyId = "YOUR_PUBLIC_KEY_ID"
const timestamp = Math.floor(Date.now() / 1000)
const nonce = randomBytes(24).toString("base64url")
const message = `MARKO-EXTERNAL-API-TOKEN-V1\n${keyId}\n${timestamp}\n${nonce}`
const signature = createHmac("sha256", apiKey).update(message).digest("hex")
const response = await fetch("https://partner-api.marko.fr/v1/auth/token", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Request-ID": "marko-auth-token",
},
body: JSON.stringify({
key_id: keyId,
timestamp,
nonce,
signature,
}),
})
const { access_token: accessToken } = await response.json(){
"access_token": "YOUR_BEARER_HERE",
"token_type": "Bearer",
"expires_in": 900,
"issued_at": "2026-04-23T10:00:00Z",
"expires_at": "2026-04-23T10:15:00Z",
"key_id": "YOUR_PUBLIC_KEY_ID",
"environment": "live",
"entity_slug": "clubfunding"
}{
"type": "about:blank",
"title": "Unauthorized",
"status": 401,
"detail": "A valid bearer token is required.",
"request_id": "req_example_partner_call"
}{
"type": "about:blank",
"title": "Forbidden",
"status": 403,
"detail": "The API key does not allow this operation.",
"request_id": "req_example_partner_call"
}{
"type": "about:blank",
"title": "Unprocessable Content",
"status": 422,
"detail": "The request payload or parameters are invalid.",
"request_id": "req_example_partner_call"
}{
"type": "about:blank",
"title": "Too Many Requests",
"status": 429,
"detail": "The request rate limit was exceeded.",
"request_id": "req_example_partner_call"
}{
"type": "about:blank",
"title": "Internal Server Error",
"status": 500,
"detail": "An unexpected server error occurred.",
"request_id": "req_example_partner_call"
}