Upload customers
Creates one claimable draft per customer. Name and email are enough. Joulo emails the claim link unless send_invite is false, in which case the links come back in the response.
Partner API key, sent as Authorization: Bearer <key>. Production keys start with jpk_live_ and work only on https://api.joulo.nl. Sandbox keys start with jpk_test_ and work only on https://api-staging.joulo.nl. Sandbox keys minted before September 2026 also start with jpk_live_. A key used on the wrong host returns 401 with a detail. A key is bound to one partner and reaches only the Partner API routes. Any other route returns 404 when it does not exist. A route that needs a scope the key lacks, such as GET /sessions, returns 403 with error: Insufficient scope and a required_scope. Every other route returns 403 with error: partner_api_key_scope. Mint and revoke keys in the partner portal. A partner has one active key at a time.
In: header
Must be true: you confirm you may supply these customers and pre-register them with Joulo.
trueThe customers to upload. At most 1,000 rows become drafts per request. The rest are rejected with over_request_limit.
When true, Joulo emails each customer the claim link. When false, the claim links come back in the response.
trueResponse Body
curl -X POST "https://api.joulo.nl/functions/v1/api/partner/customers" \
-H "Content-Type: application/json" \
-d '{
"consent": true,
"send_invite": true,
"customers": [
{
"name": "Jan de Vries",
"email": "[email protected]",
"external_ref": "KLANT-8842",
"postal_code": "6971 LB",
"house_number": "12B"
},
{
"type": "zakelijk",
"company_name": "Bedrijf B.V.",
"name": "Piet Pietersen",
"email": "[email protected]",
"kvk": "12345678"
}
]
}'{
"ok": true,
"added": 0,
"batch_id": "4da22c97-b7d5-4e31-8c3a-03870ebc7b20",
"created": [
{
"draft_id": "d998e5e8-954a-4a68-bb9e-7305e87278c0",
"email": "string",
"external_ref": "string",
"claim_url": "http://example.com",
"ean_status": "resolved",
"ean_candidates": 0
}
],
"address_ignored": [
{
"email": "string",
"reason": "invalid_postal_code"
}
],
"claim_urls": [
{
"email": "string",
"claim_url": "http://example.com"
}
],
"referral_codes": [
{
"email": "string",
"code": "string",
"matched": true
}
],
"rejected": [
{
"email": "string",
"reason": "invalid"
}
],
"skipped": {
"invalid": 0,
"reserved_domain": 0,
"missing_kvk": 0,
"already_drafted": 0,
"existing_user": 0,
"suppressed": 0,
"conflict": 0,
"over_request_limit": 0,
"over_cap": 0,
"charger_brand_unsupported": 0,
"charger_not_linked": 0,
"charger_claimed": 0
},
"cap": {
"rolling_days": 0,
"rolling_cap": 0,
"remaining_before": 0
}
}{
"error": "customers must be a non-empty array of { name, email }"
}{
"error": "Missing or invalid API token"
}{
"error": "No partner is linked to this API key"
}{
"error": "Too many requests",
"retry_after_seconds": 3
}{
"error": "Failed to create drafts"
}{
"error": "Authentication is temporarily unavailable, try again shortly"
}