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/openapivoor 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.
POST/v1/vennootschapsbelasting/returns

Dien VPB in

  • Verplicht: Idempotency-Key.
  • Verplicht: fiscalYear, rsin en taxableProfit.
  • Voor aangeleverde officiële VPB XBRL is minimaal fiscalYear, rsin en xbrlContent nodig.
  • Optioneel: lossCarryForward, innovationBoxProfit, innovationBoxRate, filingReference, xbrlContent en software metadata. Voor een officiële nul-aangifte gebruik je zeroReturn samen met companyName, bookYearStart, bookYearEnd, taxpayerType. De software* velden zijn optionele overrides; standaard hergebruikt Winstwaker dezelfde Digipoort software metadata als de andere belastingstromen.
  • Geldbedragen gebruiken maximaal 2 decimalen. innovationBoxRate gebruikt maximaal 4 decimalen. Overpreciese input wordt geblokkeerd in plaats van stil afgerond.
  • In live mode is officiële VPB XBRL verplicht via xbrlContent, inclusief een officiële schemaRef naar de actuele VPB taxonomy, tenzij je zeroReturn gebruikt met de vereiste nul-aangiftevelden zodat Winstwaker zelf een officiële instance opbouwt. xbrlContent en zeroReturn mogen niet samen worden gebruikt. Momenteel zijn live de jaren 2024 en 2025 geconfigureerd. In test mode mag Winstwaker generated smoke/test XBRL gebruiken.
  • 202 bij succesvolle submit, 200 bij idempotent replay.
  • Typische foutcodes: VALIDATION_BLOCKED, CONFLICT_IDEMPOTENCY, CREDITS_INSUFFICIENT, DIGIPOORT_SUBMIT_FAILED.
GET/v1/vennootschapsbelasting/returns/{requestId}

VPB status opvragen

  • refresh=true|false (default true).
  • Respons bevat fiscal_year, rsin, xbrl_source, submission en Digipoort metadata.
  • Bij statusrefresh worden Digipoort statussen teruggegeven in data.digipoort.statuses.
  • Controleer data.digipoort.refresh om te zien of de laatste refresh rechtstreeks uit Digipoort kwam of uit cache.
  • 200 bij gevonden request, 404 met REQUEST_NOT_FOUND als request onbekend is.
POST/v1/inkomstenbelasting/uitstelverzoeken

Dien IB-uitstel in

  • Verplicht: Idempotency-Key.
  • Verplicht: fiscalYear of fiscal_year met waarde 2024 of 2025.
  • In test mode verplicht: consultant.identificationNumber (9 cijfers), consultant.beconNumber (6 cijfers), consultant.surname en minimaal 1 requests[] regel. In live mode mag consultant wegblijven als Winstwaker een globale admin-config heeft opgeslagen.
  • Voor aanvullend uitstel gebruik je requestType = 6 of aanvullend_uitstel plus verplichte specialMotivation.
  • 202 betekent technische Digipoort-submit; inhoudelijke toekenning of afwijzing volgt daarna via SBU.
  • Typische foutcodes: VALIDATION_BLOCKED, CONFLICT_IDEMPOTENCY, CREDITS_INSUFFICIENT, DIGIPOORT_SUBMIT_FAILED.
GET/v1/inkomstenbelasting/uitstelverzoeken/{requestId}

IB-uitstel status opvragen

  • refresh=true|false (default true).
  • Respons bevat zowel data.digipoort voor transportstatus als data.business_status voor de SBU-handoff.
  • business_status.grant_status = PENDING_SBU betekent nog geen inhoudelijke beslissing.
  • Bekende business-uitkomsten zijn Toegewezen, Afgewezen, Parkeerplaats en Naar handmatig.
  • 200 bij gevonden request, 404 met REQUEST_NOT_FOUND als request onbekend is.