Winstwaker API Referentie (v1)

Open MarkdownOpen OpenAPI

Begin hier: eerst de beschikbare endpoints, daarna authenticatie, respons-format en per route een werkend request-, response- en errorvoorbeeld. Alle voorbeelden op deze pagina gebruiken directe HTTP-calls via fetch, requests of curl.

Voor AI-tools is de snelste route meestal: eerst /api/developers/markdown voor de platte docs, en daarna /api/developers/openapi voor de exacte schema's en velden.

Zo gebruik je een endpoint

  1. 1. Kies een route en gebruik de voorbeeldpayload uit de rechterkolom als startpunt.
  2. 2. Stuur headers mee: voor bijna alles Authorization: Bearer ...; voor elke POST ook Idempotency-Key en Content-Type: application/json.
  3. 3. Bewaar data.request_id uit de submit-response.
  4. 4. Poll daarna de statusroute met dat request_id, meestal met refresh=true.
  5. 5. Lees status + foutcode uit status, message en errors.code.

Wat is bijna altijd nodig?

  • GET health: geen API key nodig.
  • Andere GET-routes: bearer-token verplicht.
  • Elke POST-route: bearer-token, Idempotency-Key en JSON-body verplicht.
  • Filing-routes: meestal ook ob_nummer en een periode.
  • Status ophalen: gebruik hetzelfde request_id dat je na submit terugkrijgt.
Bouw je met AI? Gebruik https://winstwaker.nl/api/developers/llms als contextbron.

Authenticatie

Alleen GET /v1/health is publiek. Alle andere routes gebruiken bearer-auth en voor elke create-call moet je ook een stabiele Idempotency-Key meesturen.

Minimale POST-opbouw

POST /v1/icp/returns
Authorization: Bearer ww_live_...
Idempotency-Key: icp-2026-q1-001
Content-Type: application/json

{
  "ob_nummer": "NL123456789B01",
  "periode": "2026-Q1",
  "entries": [...]
}
  • GET /v1/health is publiek.
  • Alle andere endpoints vereisen Authorization: Bearer ....
  • ww_live_... voor live mode, ww_test_... voor test mode.
  • Create POST routes vereisen altijd Idempotency-Key.
  • Gebruik voor retries exact dezelfde Idempotency-Key zolang de payload gelijk blijft.

Respons-structuur

{
  "ok": true,
  "request_id": "uuid",
  "mode": "live",
  "status": "ACCEPTED | SUBMITTED | ...",
  "message": "Leesbare status",
  "data": {},
  "breakdown": {},
  "errors": null
}
{
  "ok": false,
  "request_id": "uuid",
  "mode": "live",
  "status": "ERROR",
  "message": "Leesbare foutmelding",
  "data": null,
  "breakdown": null,
  "errors": { "code": "AUTH_INVALID_KEY", "details": {} }
}

Rate-limieten

  • X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
  • Bij 429 RATE_LIMIT_EXCEEDED wordt ook Retry-After meegestuurd.

Foutcodes

  • AUTH_MISSING_BEARER, AUTH_INVALID_KEY, AUTH_IP_NOT_ALLOWED.
  • AUTH_SCOPE_MISSING, AUTH_KEY_MODE_MISMATCH.
  • RATE_LIMIT_EXCEEDED.
  • VALIDATION_MISSING_IDEMPOTENCY_KEY, VALIDATION_BLOCKED.
  • CONFLICT_IDEMPOTENCY, REQUEST_NOT_FOUND.
  • CREDITS_INSUFFICIENT, DIGIPOORT_SUBMIT_FAILED.

Webhook-aflevering voor deze developer-v1 flow is momenteel niet publiek gedocumenteerd; gebruik status-endpoints met refresh=true.

GET/v1/health

Statuscheck (publiek)

Geeft operational of degraded terug.

  • 200: service is operationeel.
  • 503: service is degraded (bijv. datastore tijdelijk niet bereikbaar).
GET/v1/credits/balance

Haal creditsaldo op

Optionele query: mode=live|test. Zonder mode krijg je beide balansen.

  • 200: saldo(s) opgehaald.
  • Typische foutcodes: AUTH_MISSING_BEARER, AUTH_INVALID_KEY, RATE_LIMIT_EXCEEDED.
GET/v1/credits/events

Haal credit-events op

  • mode=live|test (optioneel).
  • limit (default 25, max 100).
  • cursor voor paginatie.
  • 200: events met next_cursor.
  • Typische foutcodes: VALIDATION_INVALID_MODE, auth-fouten en rate-limitfouten.
GET/v1/usage/summary

Gebruiks-overzicht

Query: period=day|month (default day).

  • 200: aggregatie van successful, failed, blocked, pending.
  • Typische foutcodes: VALIDATION_INVALID_PERIOD, auth-fouten en rate-limitfouten.
POST/v1/omzetbelasting/returns

Dien omzetbelasting in

  • Verplicht: Idempotency-Key.
  • Gebruik ob_nummer of obNummer.
  • Gebruik periode in YYYY-Q[1-4] of year + quarter.
  • Input via vatData/vat_data of quickstart met omzet + btw_hoog.
  • 202 bij succesvolle submit, 200 bij idempotent replay.
  • Typische foutcodes: VALIDATION_MISSING_IDEMPOTENCY_KEY, VALIDATION_BLOCKED, CONFLICT_IDEMPOTENCY, CREDITS_INSUFFICIENT, DIGIPOORT_SUBMIT_FAILED.
GET/v1/omzetbelasting/returns/{requestId}

BTW status opvragen

  • refresh=true|false (default true).
  • Respons bevat endpoint-status, Digipoort metadata en eventuele foutcontext.
  • 200 bij gevonden request, 404 met REQUEST_NOT_FOUND als request onbekend is.
POST/v1/icp/returns

Dien ICP-opgaaf in

  • Verplicht: Idempotency-Key.
  • Gebruik ob_nummer of obNummer plus periode of year + quarter.
  • Vul entries[] met minimaal country_code, vat_number en een bedrag. type is L, D of B.
  • 202 bij succesvolle submit, 200 bij idempotent replay.
  • Typische foutcodes: VALIDATION_BLOCKED, CONFLICT_IDEMPOTENCY, CREDITS_INSUFFICIENT, DIGIPOORT_SUBMIT_FAILED.
GET/v1/icp/returns/{requestId}

ICP status opvragen

  • refresh=true|false (default true).
  • Respons bevat de huidige request-status plus Digipoort metadata zoals winstwaker_kenmerk, aanleverkenmerk en statussen.
  • Digipoort-codes zoals 301 en 405 zijn voortgangssignalen; ze betekenen niet automatisch afkeur.
  • 200 bij gevonden request, 404 met REQUEST_NOT_FOUND als request onbekend is.
POST/v1/oss/returns

Dien OSS-melding in

  • Scope is nu OBU (Unieregeling).
  • Verplicht: Idempotency-Key, periode en minimaal 1 regel in lines[].
  • Gebruik per regel member_state_of_consumption, supply_type, member_state_type, eu_member_state, rate_type, rate en taxable_amount.
  • corrections[] is optioneel voor correcties per lidstaat.
  • 202 bij succesvolle submit, 200 bij idempotent replay.
GET/v1/oss/returns/{requestId}

OSS status opvragen

  • refresh=true|false (default true).
  • Respons bevat endpoint-status, Digipoort metadata en eventuele foutcontext.
  • Ook voor OSS zijn 301 en 405 normale voortgangssignalen in de keten.
  • 200 bij gevonden request, 404 met REQUEST_NOT_FOUND als request onbekend is.
POST/v1/dividendbelasting/returns

Dien dividendbelasting in

  • Verplicht: Idempotency-Key.
  • Verplicht: distributionDate, grossDividend, dividendTax, netDividend.
  • Verplicht: withholdingEntityName, withholdingEntityRsin, beneficiaries[].
  • 202 bij succesvolle submit, 200 bij idempotent replay.
  • Typische foutcodes: VALIDATION_BLOCKED, CONFLICT_IDEMPOTENCY, CREDITS_INSUFFICIENT, DIGIPOORT_SUBMIT_FAILED.
GET/v1/dividendbelasting/returns/{requestId}

Dividend status opvragen

  • refresh=true|false (default true).
  • Respons bevat Digipoort metadata inclusief winstwaker_kenmerk en statussen.
  • 200 bij gevonden request, 404 met REQUEST_NOT_FOUND als request onbekend is.