JouloDocs

Partner API

Upload and track pre-registered customers programmatically with a per-partner API key

The Partner API is the programmatic version of the partner portal's voor-aanmelden flow. Push customers from your own CRM or installation pipeline; name and email are enough. Each row becomes a claimable draft. The customer receives a personal claim link, confirms their details and signs the ERE authorization themselves. Attribution to your partner account happens at claim time.

Partners with their own app can run the whole onboarding inside it, from upload to a submitted registration. See Onboarding inside your app.

It is available to approved Joulo partners with a portal account on partners.joulo.nl.

Getting an API key

  1. Log in at partners.joulo.nl.
  2. Open API-koppeling.
  3. Create a key. The secret starts with jpk_live_ and is shown once • only a SHA-256 hash is stored.

A partner has exactly one active key at a time: minting a new key revokes the previous one (rotation model). Keys can also be revoked from the same page.

Store the key in an environment variable or secrets manager. If a key leaks, mint a new one • the old key stops working immediately.

Base URL and authentication

https://api.joulo.nl/functions/v1/api

Send the key as a bearer token on every request:

curl https://api.joulo.nl/functions/v1/api/partner/me \
  -H "Authorization: Bearer jpk_live_..."

Test against the sandbox first. It has its own base URL and its own key.

What a key can reach

An API key is bound to one partner. It uploads that partner's customers, reads them back and reads the partner's own profile. It changes nothing else: company settings, payout IBAN, branding, the return URL of your app and the keys themselves stay in the portal.

MethodPathPurpose
GET/meCheck the key • see What a key reads about you
GET/partner/mePartner profile, including the app_return_url of your app
GET/partner/draftsPre-registered customers awaiting claim
GET/partner/customersAttributed customers • identified when you brought them in, pseudonymised for pure self-signups
GET/partner/ere-positionsPer-EAN ERE position in bulk • see ERE positions
GET/partner/referral-codes/checkCheck a friend's referral code live • see Friend referral codes
POST/partner/drafts/importBulk import in the CSV row shape
POST/partner/customersUpload customers • see Upload customers
POST/partner/drafts/auth-linkShort-lived sign-in link that opens the onboarding inside your app • see Onboarding inside your app

A request outside this table gets one of three answers. We check them in this order:

  1. 404 with error: "Not found" when the route does not exist.
  2. 403 with error: "Insufficient scope" and a required_scope when the route needs a scope the key does not hold, such as GET /sessions.
  3. 403 with error: "partner_api_key_scope" for every other route. These are portal routes: the key's scopes (partners:read, partners:write) cover them, but a key may not call them.

On the sandbox host the key also reaches the sandbox helpers under /sandbox/.

What a key reads about you

The key reads your partner record in full, commercial terms included. Give it only to someone who may see those.

  • GET /partner/me returns the record the portal shows. That includes your revenue share and other contract terms, KvK and VAT number, and billing address. It also holds the payout IBAN of your primary account, masked as NL91 **** **** 00. The key can change none of it.
  • GET /me answers for your primary account: its user_id, e-mail address, name and effective_fee_pct. That fee is the account's own fee as a Joulo customer, not your partner terms. Without a primary account, user_id is the partner id and the e-mail and name fields are null.

Rate limits

Two token buckets apply; throttled requests return 429 with a Retry-After header:

  • Pre-auth, per IP + token prefix: burst of 30, refill 1 request/second.
  • Per identity, after authentication: burst of 60, refill 1 request/second.

Both are comfortably above a normal integration's load (for example a poll-per-minute sync or a batched nightly upload).

OAuth2 and the portal

The partner portal itself talks to the same endpoints with an OAuth2 session (partners:read / partners:write scopes). For server-to-server integrations, the API key is the supported path • it never acts as a Joulo user and cannot be used to impersonate one.