# MCP server
Source: https://docs.developers.mijnklantportaal.nl/ai/mcp
Our MCP server is currently available in beta.
## What is an MCP server?
MCP (Model Context Protocol) is an open standard that lets AI applications (like chat assistants, IDE copilots, agents, and similar tools) connect
to external systems in a consistent way. Instead of every AI application needing custom, one-off integration code for every external service, MCP
defines a common protocol that both sides speak.
## MCP endpoint
Currently, MijnKlantportaal provides only an MCP server for the managing portal. The MCP server for the managing portal can be found at:
`https://mcp.mijnklantportaal.nl/v1/manage`
## Authentication
Authentication for the MCP server runs over OAuth. Once you connect to the MCP server, you are asked to authenticate with your MijnKlantportaal admin
account. After logging in, you will be prompted to give permission to the MCP server to access your data.
## What can the MCP server do?
You can ask the agent to read and interact with your data. For example, you can ask the agent to summarize your open invoices and then ask to close them
or create a new one.
You can consult and interact with the following data via the MCP server:
* Agreements
* Appointments
* Customers
* Customer groups
* Offers & invoices
##### Privacy warning for free LLM users
Your conversations may be used for AI training. Most free-tier AI services retain and analyze your messages to improve their models. This means your
questions, personal information, and discussions could become part of their training data, including the data fetched from MijnKlantportaal.
# Create agreement
Source: https://docs.developers.mijnklantportaal.nl/api-reference/agreements-api/create-agreement
/openapi.yaml post /agreements
Creating a new agreement. **Note**: This endpoint accepts only `multipart/form-data`.
# Delete Agreement
Source: https://docs.developers.mijnklantportaal.nl/api-reference/agreements-api/delete-agreement
/openapi.yaml delete /agreements/{agreementId}
Delete an Agreement by ID
# Download Agreement document
Source: https://docs.developers.mijnklantportaal.nl/api-reference/agreements-api/download-agreement-document
/openapi.yaml get /agreements/{agreementId}/documents/{documentId}/download
Receive a URL to download the document. Please note that the URL is valid for 5 minutes.
# Download Legal Statement for Agreement
Source: https://docs.developers.mijnklantportaal.nl/api-reference/agreements-api/download-legal-statement-for-agreement
/openapi.yaml get /agreements/{agreementId}/documents/legal-statement/download
Receive a URL to download the legal statement. Please note that you can only request the document when the agreement is fully signed. The URL is valid for 5 minutes.
# Get Agreement
Source: https://docs.developers.mijnklantportaal.nl/api-reference/agreements-api/get-agreement
/openapi.yaml get /agreements/{agreementId}
Get an Agreement by ID
# List Agreements
Source: https://docs.developers.mijnklantportaal.nl/api-reference/agreements-api/list-agreements
/openapi.yaml get /agreements
Getting all agreements as paginated response
# Cancel appointment
Source: https://docs.developers.mijnklantportaal.nl/api-reference/appointments-api/cancel-appointment
/openapi.yaml delete /appointments/{appointmentId}
Cancel an existing appointment
# Change appointment status
Source: https://docs.developers.mijnklantportaal.nl/api-reference/appointments-api/change-appointment-status
/openapi.yaml patch /appointments/{appointmentId}
Confirm or cancel a pending appointment
# Get AI summary of Appointment
Source: https://docs.developers.mijnklantportaal.nl/api-reference/appointments-api/get-ai-summary-of-appointment
/openapi.yaml get /appointments/{appointmentId}/summary
Get the AI summary of an appointment by the appointment ID
# Get Appointment
Source: https://docs.developers.mijnklantportaal.nl/api-reference/appointments-api/get-appointment
/openapi.yaml get /appointments/{appointmentId}
Get an appointment by an ID
# List Appointments
Source: https://docs.developers.mijnklantportaal.nl/api-reference/appointments-api/list-appointments
/openapi.yaml get /appointments
Getting a NON-PAGINATED list of all the appointments in the given period. The result includes all appointments, also canceled and pending once.
# Schedule Appointment
Source: https://docs.developers.mijnklantportaal.nl/api-reference/appointments-api/schedule-appointment
/openapi.yaml post /appointments
Schedule a new appointment
# Add Customers to Customer Group
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-groups-api/add-customers-to-customer-group
/openapi.yaml post /customer-groups/{customerGroupId}/customers
Add one or multiple customers to the Customer Group. Please note that unknown or wrong Customer IDs are ignored, no error is returned.
# Create Customer Group
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-groups-api/create-customer-group
/openapi.yaml post /customer-groups
Create a new Customer Group
# Delete customer group
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-groups-api/delete-customer-group
/openapi.yaml delete /customer-groups/{customerGroupId}
Delete the customer group for the given ID
# Edit Customer Group
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-groups-api/edit-customer-group
/openapi.yaml patch /customer-groups/{customerGroupId}
Make changes to an existing customer group
# Get Customer Group
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-groups-api/get-customer-group
/openapi.yaml get /customer-groups/{customerGroupId}
Get a specific Customer Group
# List Customer Groups
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-groups-api/list-customer-groups
/openapi.yaml get /customer-groups
Getting all the customer groups as paginated response
# List Customers in Customer Group
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-groups-api/list-customers-in-customer-group
/openapi.yaml get /customer-groups/{customerGroupId}/customers
Get all the customers in a specific Customer Group. Please note this is a NON-PAGINATED list
# Remove Customers from the Customer Group
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-groups-api/remove-customers-from-the-customer-group
/openapi.yaml delete /customer-groups/{customerGroupId}/customers
Remove one or multiple customers from the Customer Group. Please note that unknown or wrong Customer IDs are ignored, no error is returned.
# Create Customer Invoice
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-invoices-api/create-customer-invoice
/openapi.yaml post /customer-invoices
Add a new Customer Invoice to your portal.\
\
**Important!** Note that this request is not JSON, but a `multipart/form-data` post.
# Create manual Customer Invoice
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-invoices-api/create-manual-customer-invoice
/openapi.yaml post /customer-invoices/manual
Create a Customer Invoice from the ground up by providing product/service lines
# Delete Customer Invoice
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-invoices-api/delete-customer-invoice
/openapi.yaml delete /customer-invoices/{invoiceId}
Remove a Customer Invoice from your portal. Be aware that deleting an invoice will not effect your license limits
# Get Customer Invoice
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-invoices-api/get-customer-invoice
/openapi.yaml get /customer-invoices/{invoiceId}
Get a Customer Invoice by ID
# Get Customer Invoice as PDF
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-invoices-api/get-customer-invoice-as-pdf
/openapi.yaml get /customer-invoices/{invoiceId}/pdf
Receive a URL to get the invoice as PDF. Please note that the URL is valid for 5 minutes.
# List Customer Invoices
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-invoices-api/list-customer-invoices
/openapi.yaml get /customer-invoices
Getting all your customer invoices in your portal as paginated response
# Mark Customer Invoice paid
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-invoices-api/mark-customer-invoice-paid
/openapi.yaml patch /customer-invoices/{invoiceId}
Set the Customer Invoice as paid. This will, if connected, also update the integration
# Create Customer Offer
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-offers-api/create-customer-offer
/openapi.yaml post /customer-offers
Add a new Customer Offer to your portal.\
\
**Important!** Note that this request is not JSON, but a `multipart/form-data` post.
# Create manual Customer Offer
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-offers-api/create-manual-customer-offer
/openapi.yaml post /customer-offers/manual
Create a Customer Offer from the ground up by providing product/service lines
# Delete Customer Offer
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-offers-api/delete-customer-offer
/openapi.yaml delete /customer-offers/{offerId}
Remove a Customer Offer from your portal. Be aware that deleting an offer will not effect your license limits
# Get Customer Offer
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-offers-api/get-customer-offer
/openapi.yaml get /customer-offers/{offerId}
Get a Customer Offer by ID
# Get Customer Offer as PDF
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-offers-api/get-customer-offer-as-pdf
/openapi.yaml get /customer-offers/{offerId}/pdf
Receive a URL to get the offer as PDF. Please note that the URL is valid for 5 minutes.
# List Customer Offers
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-offers-api/list-customer-offers
/openapi.yaml get /customer-offers
Getting all your customer offers in your portal as paginated response
# Mark Customer Offer accepted or rejected
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-offers-api/mark-customer-offer-accepted-or-rejected
/openapi.yaml patch /customer-offers/{offerId}
Set the Customer Offer as accepted or rejected. This will, if connected, also update the integration
# Change Customer Subscription Package
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-subscription-packages-api/change-customer-subscription-package
/openapi.yaml patch /customer-subscription-packages/{packageId}
Change a Customer Subscription Package by ID
# Create Customer Subscription Package
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-subscription-packages-api/create-customer-subscription-package
/openapi.yaml post /customer-subscription-packages
Add a new Customer Subscription package.
# Delete Customer Subscription Package
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-subscription-packages-api/delete-customer-subscription-package
/openapi.yaml delete /customer-subscription-packages/{packageId}
Delete a Customer Subscription Package by ID
# Get Customer Subscription Package
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-subscription-packages-api/get-customer-subscription-package
/openapi.yaml get /customer-subscription-packages/{packageId}
Get a Customer Subscription Package by ID
# List Customer Subscription packages
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-subscription-packages-api/list-customer-subscription-packages
/openapi.yaml get /customer-subscription-packages
Getting all customer subscription packages as paginated response
# Sign-up a customer for a Customer Subscription Package
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-subscription-packages-api/sign-up-a-customer-for-a-customer-subscription-package
/openapi.yaml post /customer-subscription-packages/{packageId}/sign-up
Sign-up for a customer for a Customer Subscription Package by ID.
# Sign-up a non-customer for a Customer Subscription Package
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-subscription-packages-api/sign-up-a-non-customer-for-a-customer-subscription-package
/openapi.yaml post /customer-subscription-packages/{packageId}/sign-up/
Sign-up for a non-customer for a Customer Subscription Package by ID. A payment link will be generated.
# Change Customer Subscription
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-subscriptions-api/change-customer-subscription
/openapi.yaml patch /customer-subscriptions/{subscriptionId}
Change a Customer Subscription by ID
# Create Customer Subscription
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-subscriptions-api/create-customer-subscription
/openapi.yaml post /customer-subscriptions
Add a new Customer Subscription.
# Delete Customer Subscription
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-subscriptions-api/delete-customer-subscription
/openapi.yaml delete /customer-subscriptions/{subscriptionId}
Remove a Customer Subscription from your portal.
# Get Customer Subscription
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-subscriptions-api/get-customer-subscription
/openapi.yaml get /customer-subscriptions/{subscriptionId}
Get a Customer Subscription by ID
# List Customer Subscriptions
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customer-subscriptions-api/list-customer-subscriptions
/openapi.yaml get /customer-subscriptions
Getting all your customer subscriptions in your portal as paginated response
# Create Customer
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customers-api/create-customer
/openapi.yaml post /customers
Adding a new customer to your portal
# Delete customer
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customers-api/delete-customer
/openapi.yaml delete /customers/{customerId}
Delete the customer for the given ID
# Edit Customer
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customers-api/edit-customer
/openapi.yaml patch /customers/{customerId}
Make changes to an existing customer.\
\
Allthough all body fields are optional, at least one should be provided.
# Get Customer
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customers-api/get-customer
/openapi.yaml get /customers/{customerId}
Get a customer by an ID
# Link Customer
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customers-api/link-customer
/openapi.yaml post /customers/{customerId}/link
Link a customer to a customer in a bookkeeping integration
# List Customers
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customers-api/list-customers
/openapi.yaml get /customers
Getting all your customers in your portal as paginated response
# Unlink Customer
Source: https://docs.developers.mijnklantportaal.nl/api-reference/customers-api/unlink-customer
/openapi.yaml delete /customers/{customerId}/link
Unlink a customer from a bookkeeping integration
# Create File Request
Source: https://docs.developers.mijnklantportaal.nl/api-reference/file-request-api/create-file-request
/openapi.yaml post /file-requests
Create a File Request to a customer or with a public link
# Delete File Request
Source: https://docs.developers.mijnklantportaal.nl/api-reference/file-request-api/delete-file-request
/openapi.yaml delete /file-requests/{requestId}
Deletes a File Request, and the request only. Uploaded files from this request will **not** be deleted
# Get File Request
Source: https://docs.developers.mijnklantportaal.nl/api-reference/file-request-api/get-file-request
/openapi.yaml get /file-requests/{requestId}
Get a specific File Request
# List File Requests
Source: https://docs.developers.mijnklantportaal.nl/api-reference/file-request-api/list-file-requests
/openapi.yaml get /file-requests
Getting all your File Request entities as paginated response
# Create File Share
Source: https://docs.developers.mijnklantportaal.nl/api-reference/file-share-api/create-file-share
/openapi.yaml post /file-shares
Share Directories and Files with a Customer or via a public link
# Delete File Share
Source: https://docs.developers.mijnklantportaal.nl/api-reference/file-share-api/delete-file-share
/openapi.yaml delete /file-shares/{shareId}
Remove a File Share and so stop sharing the content
# Get File Share
Source: https://docs.developers.mijnklantportaal.nl/api-reference/file-share-api/get-file-share
/openapi.yaml get /file-shares/{shareId}
Get the File Share for the given ID
# List File Shares
Source: https://docs.developers.mijnklantportaal.nl/api-reference/file-share-api/list-file-shares
/openapi.yaml get /file-shares
Getting all your File Share entities as paginated response
# Delete File or Directory
Source: https://docs.developers.mijnklantportaal.nl/api-reference/files-api/delete-file-or-directory
/openapi.yaml delete /files/{fileOrDirId}
Delete a file or directory by the ID
# Download file
Source: https://docs.developers.mijnklantportaal.nl/api-reference/files-api/download-file
/openapi.yaml get /files/{fileId}/download
Receive a URL to download a file. Please note that the URL is valid for 5 minutes. Note: only files can be downloaded!
# Get File or Directory
Source: https://docs.developers.mijnklantportaal.nl/api-reference/files-api/get-file-or-directory
/openapi.yaml get /files/{fileOrDirId}
Get a specific file or directory based on ID
# List Files and Directories
Source: https://docs.developers.mijnklantportaal.nl/api-reference/files-api/list-files-and-directories
/openapi.yaml get /files
Getting all your files and directories in the given directory
# Uploading a file or creating a directory
Source: https://docs.developers.mijnklantportaal.nl/api-reference/files-api/uploading-a-file-or-creating-a-directory
/openapi.yaml post /files
Upload a file or create a directory to provide one of the body params. You can not provide both at the same time. **Note**: If you upload a file, use the `multipart/form-data` post. For creating a directory, use the regular `application/json` post.
# Get MijnKlantportaal Invoice
Source: https://docs.developers.mijnklantportaal.nl/api-reference/invoices-api/get-mijnklantportaal-invoice
/openapi.yaml get /invoices/{invoiceId}
Get a specific MijnKlantportaal invoice
# Get PDF for MijnKlantportaal Invoice
Source: https://docs.developers.mijnklantportaal.nl/api-reference/invoices-api/get-pdf-for-mijnklantportaal-invoice
/openapi.yaml get /invoices/{invoiceId}/pdf
Get the PDF file for a specific MijnKlantportaal invoice
# List MijnKlantportaal invoices
Source: https://docs.developers.mijnklantportaal.nl/api-reference/invoices-api/list-mijnklantportaal-invoices
/openapi.yaml get /invoices
Getting all the invoices sent by MijnKlantportaal for license fees and other costs
# Get information from token
Source: https://docs.developers.mijnklantportaal.nl/api-reference/me-api/get-information-from-token
/openapi.yaml get /me
Getting all information about the used token and the connected user, installation and license details
# Close Payment Link
Source: https://docs.developers.mijnklantportaal.nl/api-reference/payment-links-api/close-payment-link
/openapi.yaml delete /payment-links/{linkId}
Close the Payment Link so it can not be used anymore. Useful for reusable links.
# Create Payment Link
Source: https://docs.developers.mijnklantportaal.nl/api-reference/payment-links-api/create-payment-link
/openapi.yaml post /payment-links
Add a new Payment Link.
# Get Payment Link
Source: https://docs.developers.mijnklantportaal.nl/api-reference/payment-links-api/get-payment-link
/openapi.yaml get /payment-links/{linkId}
Get a Payment Link by ID
# List Payment Link Payments
Source: https://docs.developers.mijnklantportaal.nl/api-reference/payment-links-api/list-payment-link-payments
/openapi.yaml get /payment-links/{linkId}/payments
# List Payment Links
Source: https://docs.developers.mijnklantportaal.nl/api-reference/payment-links-api/list-payment-links
/openapi.yaml get /payment-links
Getting all your payment links as paginated response
# Create Punch Card
Source: https://docs.developers.mijnklantportaal.nl/api-reference/punch-cards-api/create-punch-card
/openapi.yaml post /punch-cards
Create a new Punch Card.
# Delete Punch Card
Source: https://docs.developers.mijnklantportaal.nl/api-reference/punch-cards-api/delete-punch-card
/openapi.yaml delete /punch-cards/{punchCardId}
Deletes the Punch Card and all sold cards related to it.
# Edit Punch Card
Source: https://docs.developers.mijnklantportaal.nl/api-reference/punch-cards-api/edit-punch-card
/openapi.yaml patch /punch-cards/{punchCardId}
Edit a Punch Card by ID
# Get an issued Punch Card
Source: https://docs.developers.mijnklantportaal.nl/api-reference/punch-cards-api/get-an-issued-punch-card
/openapi.yaml get /punch-cards/{punchCardId}/issued/{issuedPunchCardId}
Get an issued Punch Card by it's ID and those of the card itself
# Get Punch Card
Source: https://docs.developers.mijnklantportaal.nl/api-reference/punch-cards-api/get-punch-card
/openapi.yaml get /punch-cards/{punchCardId}
Get a Punch Card by ID
# Issue new Punch Card
Source: https://docs.developers.mijnklantportaal.nl/api-reference/punch-cards-api/issue-new-punch-card
/openapi.yaml post /punch-cards/{punchCardId}/issued
Issue a new Punch Card to a customer.
# List issued cards for Punch Card
Source: https://docs.developers.mijnklantportaal.nl/api-reference/punch-cards-api/list-issued-cards-for-punch-card
/openapi.yaml get /punch-cards/{punchCardId}/issued
Getting all issued cards for a specific punch card as paginated response
# List Punch Cards
Source: https://docs.developers.mijnklantportaal.nl/api-reference/punch-cards-api/list-punch-cards
/openapi.yaml get /punch-cards
Getting all punch cards as paginated response
# Stamp an issued Punch Card
Source: https://docs.developers.mijnklantportaal.nl/api-reference/punch-cards-api/stamp-an-issued-punch-card
/openapi.yaml post /punch-cards/{punchCardId}/issued/{issuedPunchCardId}/stamp
Add a stamp to an issued Punch Card by it's ID and those of the card itself
# Add message to the ticket
Source: https://docs.developers.mijnklantportaal.nl/api-reference/tickets-api/add-message-to-the-ticket
/openapi.yaml post /tickets/{ticketId}
Add a new message as reply to the ticket. Please note that replying to a closed ticket will reopen it. You can not add a message to a ticket created from live chat via the API
# Close the ticket
Source: https://docs.developers.mijnklantportaal.nl/api-reference/tickets-api/close-the-ticket
/openapi.yaml patch /tickets/{ticketId}
Mark the ticket as closed
# Download Ticket message attachment
Source: https://docs.developers.mijnklantportaal.nl/api-reference/tickets-api/download-ticket-message-attachment
/openapi.yaml get /tickets/{ticketId}/message/{messageId}/attachment/{attachmentId}/download
Receive a URL to download the attachment. Please note that the URL is valid for 5 minutes.
# Get Ticket record
Source: https://docs.developers.mijnklantportaal.nl/api-reference/tickets-api/get-ticket-record
/openapi.yaml get /tickets/{ticketId}
Get a ticket with the messages belonging to it
# List ticket records
Source: https://docs.developers.mijnklantportaal.nl/api-reference/tickets-api/list-ticket-records
/openapi.yaml get /tickets
Paginated response with all tickets created by customers
# Upload attachment to Ticket message
Source: https://docs.developers.mijnklantportaal.nl/api-reference/tickets-api/upload-attachment-to-ticket-message
/openapi.yaml post /tickets/{ticketId}/message/{messageId}/attachment
Add an attachment to an already posted Ticket message. Adding an attachment is only possible in the first 5 minutes after creating the message. Chat conversations do not support attachments.
# Create Webhook record
Source: https://docs.developers.mijnklantportaal.nl/api-reference/webhooks-api/create-webhook-record
/openapi.yaml post /webhooks
# Get Webhook record
Source: https://docs.developers.mijnklantportaal.nl/api-reference/webhooks-api/get-webhook-record
/openapi.yaml get /webhooks/{webhookId}
# List Webhook records
Source: https://docs.developers.mijnklantportaal.nl/api-reference/webhooks-api/list-webhook-records
/openapi.yaml get /webhooks
Paginated response with all the active webhooks on your account
# Remove Webhook record
Source: https://docs.developers.mijnklantportaal.nl/api-reference/webhooks-api/remove-webhook-record
/openapi.yaml delete /webhooks/{webhookId}
# Forms
Source: https://docs.developers.mijnklantportaal.nl/cms/forms
This page gives instruction for working with Forms and your server. It's also possible to receive the entered data per email or saved it right into MijnKlantportaal, which does not require technical skills.
With Forms, you can bring your own interacting form to your customer portal. You can build whatever you want as long as it can be formatted as a submittable form, like a settings page for hosting settings. To let your form interact with your API, you should know how we call your APIs to send and (optional) retrieve data.
##### Always respond with a 2xx status code
If your endpoint does not response with a status code in the 200-range, MijnKlantportaal will consider the request, both sending and retrieving, as failed and so showing your customer an error message.
## Sending data
When your customer submits the form, we call your API endpoint with the HTTP method which you set yourself. The request will always contain the following headers:
| Header | Description | Example |
| - | - | - |
| `X-Customer-Id` | The ID of the customer which submits the form | `cst_123abc456def` |
| `X-Form-Id` | The ID of the form which is submitted | `frm_123abc456def` |
The body will contain JSON with your field names and the value entered by your customer. In case of a `GET` method, the request will be query parameters. An example:
**Your form:**
| Field name | Field value |
| - | - |
| `name` | `John Doe` |
| `age` | `20` |
| `sex` | `male` |
**The request body or query parameters to your endpoint:**
```json JSON theme={null}
{
"name": "John Doe",
"age": 20,
"sex": "male"
}
```
```txt Query params theme={null}
?name=John+Doe&age=20&sex=male
```
## Retrieving data
You can pre-fill your form by setting a retrieving data endpoint. You can choose between a `GET` or `POST` method.
The endpoint should return a JSON-object with the fields which you have specified. **Any missing fields in your response will be considered as `null` and so left empty.** Any extra fields which are not corresponding with any of your form fields, will be discarded.
The request will always contain the following headers:
| Header | Description | Example |
| - | - | - |
| `Accept` | MijnKlantportaal always expects a JSON-object | `application/json` |
| `X-Customer-Id` | The ID of the customer the data is for | `cst_123abc456def` |
| `X-Form-Id` | The ID of the form to fill | `frm_123abc456def` |
**Your form:**
| Field name |
| - |
| `name` |
| `sex` |
| `age` |
**The response body:**
```json JSON theme={null}
{
"name": "John Doe",
"nationality": "Dutch", // Will be ignored since field 'nationality' does not exist
"sex": "male"
// 'age' will be left empty in the form, since no data is returned for that field
}
```
# Dynamic HTML
Source: https://docs.developers.mijnklantportaal.nl/cms/pages-dynamic-html
Adding a Dynamic HTML block to your Page will give you full control over the content on the page. Your server decides what content will be displayed. To let your portal page interact with your server, you should know how we call your endpoint to get the HTML content.
## The request
The moment your customer will open your Page, a HTTP-request will done towards the endpoint you have provided. You can protect this endpoint with Basic Auth or an `Authentication` header. To identify the customer which opened the page, do we send an header with the identifier.
| Header | Description | Example |
| - | - | - |
| `Accept` | MijnKlantportaal accepts (and expects) HTML | `text/html` |
| `X-Customer-Id` | The ID of the customer which opened the page | `cst_123abc456def` |
| `X-Page-Id` | The ID of the page which needs your HTML content | `pag_123abc456def` |
## The response
The request is covered by authentication, but the response should be protected too. Therefor do we expect a certain content in your response to make your HTML enter your MijnKlantportaal page. Add the following headers to your response:
| Header | Description | Example |
| - | - | - |
| `Content-Type` | Let our server know that you, indeed, are sending HTML as response | `text/html` |
| `X-Checksum` | A checksum to validate that the response is actually coming from your server. See further on this page how to generate this | `1e5e791547c14e581e09...` |
The body should be the actual, raw, HTML text you want to add to your Page. Failure in providing the correct headers will result in a rejected call to your endpoint and so will not show up your HTML.
## The `X-Checksum` header
To make sure that the HTML is actually coming from your server, you have to add a checksum in the header. This checksum will be a Hash-based Message Authentication Code (HMAC) signature based on some values. This signature needs to be included in your response in the `X-Checksum` header. The data that needs to be used are:
| Type | Value |
| - | - |
| Algorithm | SHA256 |
| Data | IDOfYourCustomer,IDOfYourPage - For example: `cst_123abc456def,pag_123abc456def`. Be aware: no spaces! |
| Key | *The key you have provided when creating the block* |
# Authentication
Source: https://docs.developers.mijnklantportaal.nl/getting-started/authentication
## Authenticate to the API
When calling the API, you have to provide an Authentication Token. No matter what token you use, all of them are `Bearer` tokens and have to be provided in the
`Authentication` header in your request.
**Example:**
`Authentication: Bearer `
## Authentication types
To make sure that we return only the correct data, do you need to authenticate yourself (as MijnKlantportaal user or third party developer) to our API. The way
of authentication is decided in what role you talk to the API:
* **MijnKlantportaal user**: API Key
* **Third party developer**: OAuth Access Token (OAT)
### API Key
If you want to access the API for your own customer portal, the best way to authenticate yourself is with an API Key. You can create this API Key in the manage portal.
To get access, follow these steps:
Open your manage portal and log in.
Go to 'Settings API Keys' and press the *Create API key*-button in the top right corner. Specify to which [scopes](/oauth/scopes)
this key can get access to.
Once created, we show you the API Key just **once**, so save it directly on a secure place.
Treat your API Key like a password. Do **not** share it with anyone!
### OAuth Access Token (OAT)
When you are developing software and want to integrate MijnKlantportaal APIs, you should use OAuth to get access. This is the only way to get access to someone else's MijnKlantportaal
account.
Never ask MijnKlantportaal users for API Keys as third party developer!
To be able to use our OAuth solution, you should register yourself as developer and register your application. To get this done, following these steps:
Press the button in the right top corner on this page: "Developer portal". and register yourself as developer by creating a Developer Account.
Once you have your developer account and logged in into the Developer portal, you can create (and so register) your application to receive your App ID and App Secret.
Treat your App Secret like a password. Do **not** share it with anyone!
Before you get access to someone's customer portal, you have to ask permission. Compose an Authorize url with you App ID, the scopes you want access to and the other
data we need to ask the user for permission. See the documentation page "xxx" for info.
When the user gave you permission to access their portal, you should exchange the Authorization Token for an Access Token (which gives you access to the API) and
Refresh Token (to generate a new Access Token once it expires). Use the "xxx" endpoint for this.
Keep in mind that the user can always revoke your access, and so invalidate your Access and Refresh Tokens.
# Idempotency
Source: https://docs.developers.mijnklantportaal.nl/getting-started/idempotency
## What is idempotency?
Idempotency is a property of an API operation that guarantees making the same request multiple times has the same effect as making it once.
If a request is sent, and then sent again, whether due to a network timeout, a retry, a duplicate click, or a client crashing before it
received a response, the server processes it safely without creating duplicate side effects.
## How is the MijnKlantportaal API handling idempotency?
The API supports idempotency for `POST`, `PUT` and `PATCH` operations. We will ignore the header if you provide it in any other HTTP-operation.
The given key can then still be used. You can provide an idempotency key via the `Idempotency-Key` header. Our recommendation is to use
UUIDv4 strings as key. Idempotency keys are linked to API keys, so the same key can be used over multiple API authentication tokens.
If you provide a correct and unique idempotency key, the API request will be handled as expected. When the API returns a non-successful response,
the key will not be saved and so can be used again. If the first requests was successful and you provide the same payload with the same key again
then the API will return the same response with an additonal header: `Idempotency-Replayed: true`. If you provide the same key with a different body,
the request will be rejected.
Idempotency keys will be saved for **90 days** (3 months). After this window, the same key can be used again.
Keep in mind that idempotency keys can be at maximum 255 characters long. Longer keys will be rejected.
## Request example
```bash Example of creating customer theme={null}
curl --request POST \
--url https://api.mijnklantportaal.nl/v1/customers \
--header 'Authorization: Bearer apikey_abc123...' \
--header 'Idempotency-Key: 4901453f-2567-4b93-a6c7-042262dcb6d3' \
--header 'Content-Type: application/json' \
--data '
{
"companyName": "Test Company BV",
"address": "Teststreet 123",
"zipCode": "1234AB",
"city": "Amsterdam",
"primaryEmail": "john.doe@test.com",
"countryCode": "NL"
}
'
```
## Response examples
**Using the same idempotency key for the same request**
```http HTTP theme={null}
Content-Type: application/json
Idempotency-Key: 4901453f-2567-4b93-a6c7-042262dcb6d3
Idempotency-Replayed: true
{
// The same response as the first request
...
}
```
**Using the same idempotency key for another request**
```json 409 - Conflict theme={null}
{
"code": 409,
"message": "The given Idempotency-Key is already used for another request."
}
```
**Giving a too long idempotency key**
```json 400 - Bad Request theme={null}
{
"code": 400,
"message": "The Idempotency-Key can not be longer than 255 characters, yours has 300 characters. We recommend using UUIDv4 strings."
}
```
# Rate limiting
Source: https://docs.developers.mijnklantportaal.nl/getting-started/rate-limiting
## What is rate limiting?
Rate limiting is a mechanism used to control the number of requests a client can make to our API within a given timeframe.
This helps ensure fair usage, protects the stability of the system, and prevents abuse (such as automated traffic floods).
When a client exceeds the allowed request limit, the API will temporarily reject further requests and return an error response until the time window resets.
## What is the limit in the MijnKlantportaal API?
By default, each API key or access token is limited to **60 requests per minute**. This limit is applied on a rolling basis, meaning once you reach the threshold,
additional requests will be rejected until the next minute window begins. If you consistently need higher limits, please contact us to discuss your use case.
## How do I know how many requests I have left?
Every response of the API contains some headers with information about the rate limit:
| Header | Description |
| - | - |
| `X-RateLimit-Limit` | The limit that's currently applied |
| `X-RateLimit-Remaining` | Amount of calls left in the current minute |
| `retry-after` | How many seconds you have to wait until you can call the API again. Only present when you hit the limit |
| `x-ratelimit-reset` | The UNIX timestamp when the limit resets and you can make calls again. Only present when you hit the limit |
## How do I know that I hit the limit?
Once you hit the limit, we return a fixed response:
```json 429 - Too Many Requests theme={null}
{
"code": 429,
"message": "Too many requests."
}
```
# Introduction
Source: https://docs.developers.mijnklantportaal.nl/index
Welcome to the MijnKlantportaal Developer Documentation.
## Creating an account
No matter if you want to use MijnKlantportaal for yourself or just developing on the platform, you need to create a portal and account.
It will take you less than 5 minutes.
## All technical documentation, available for you right here.
You can find here all technical documentation, like the API reference and how set up other integrations with your own portal.
Check our API documentation and integrate MijnKlantportaal into your service
Register and maintain your applications and credentials.
# Authorize
Source: https://docs.developers.mijnklantportaal.nl/oauth/endpoints/authorize
GET https://manage.mijnklantportaal.nl/oauth/authorize
Ask the user permission to access their portal
Please note that the base URL for this endpoint is: `https://manage.mijnklantportaal.nl`
#### Query parameters
ID of your application you got after registering it in the Developer portal.
The URL where the user should be send to after accepting or declining the permission request.
The URL **must** be registered with your application in the Developer portal.
A random string generated by your application to prevent CSRF attacks. This value will be returned
in the redirect back to your application.
A, with spaces separated, string with the [OAuth Scopes](/oauth/scopes) you want access to.
Example: `customers.read customer.write invoices.read`
Can be `consent` or `login`.
The type of response you want to return. This should always be `code`.
#### Response
The user decides to accept or reject your request. After that, we send the user back to your `redirect_uri` and include
some information for your application. We add some query parameters to your URL:
**In case of an approval:**
The Authorization code which you need to exchange for the actual Access and Refresh tokens.
This code is valid for just a short amount of time. Exchange it as soon as you get it.
The string you set upon request. You have to check if the string matches the one you have set to ensure CSRF protection.
**In case of a rejection or error:**
The error code.
A human-readable description of the error occured.
# Generate tokens
Source: https://docs.developers.mijnklantportaal.nl/oauth/endpoints/generate-tokens
POST https://manage.mijnklantportaal.nl/oauth/tokens
Generate Access and Refresh Tokens from your Authentication Code
Please note that the base URL for this endpoint is: `https://manage.mijnklantportaal.nl`
#### Body
Type of grant you want generate tokens for. Must be always `authorization_code`.
ID of your application which you got the Authentication Code for.
The secret of your application you got after registering it in the Developer portal.
The redirect URL as registered in the Developer portal.
The Authentication Code you got on the redirect back to your application.
#### Response
The `Bearer` token you can use for accessing the MijnKlantportaal API.
The token you need to generate a new Access Token after it is expired.
Amount of seconds until the given Access Token expires.
# Refresh token
Source: https://docs.developers.mijnklantportaal.nl/oauth/endpoints/refresh-token
POST https://manage.mijnklantportaal.nl/oauth/tokens
Refresh an Access Token with the Refresh Token
Please note that the base URL for this endpoint is: `https://manage.mijnklantportaal.nl`
#### Body
Type of grant you want generate tokens for. Must be always `refresh_token`.
ID of your application which you got the Authentication Code for.
The secret of your application you got after registering it in the Developer portal.
The Refresh Token you got the moment you generated the first tokens.
#### Response
The new `Bearer` token you can use for accessing the MijnKlantportaal API.
Amount of seconds until the given Access Token expires.
# Scopes
Source: https://docs.developers.mijnklantportaal.nl/oauth/scopes
Scoping is a mechanism in OAuth 2.0 to limit an application's access to the portal of a MijnKlantportaal user. When asking the user for permission to access his/her portal, you
have to provide the areas/data (scopes) you want to get access to, as well if you want just to read the data (`*.read`) or also be able to create, delete and/or make changes to
it (`*.write`).
## Available scopes
| Scope | Description |
| - | - |
| `agreements.read` | Getting the agreements and the documents related to it. |
| `agreements.write` | Creating and deleting agreements |
| `appointments.read` | Getting the appointments, both planned as pending records |
| `appointments.write` | Scheduling, changing, and canceling appointments |
| `businessoperations.read` | Getting the invoices sent to the user from MijnKlantportaal |
| `customers.read` | Getting the customers, and their data, and customer groups |
| `customers.write` | Creating, editing and deleting customers and customer groups |
| `files.read` | Getting files and be able to download them |
| `files.write` | Uploading and deleting files |
| `filerequest.read` | Getting file requests and the records of delivered files (not able to download) |
| `filerequest.write` | Creating and deleting file requests |
| `fileshare.read` | Getting the file share records and so see what files have been shared |
| `fileshare.write` | Sharing existing files with customers or via a public link |
| `offers.read` | Getting the offers in MijnKlantportaal and the PDF of it |
| `offers.write` | Being able to create new offers and/or upload new offer PDFs for customers, as well marking existing once accepted or declined |
| `invoices.read` | Getting the invoices in MijnKlantportaal and the PDF of it |
| `paymentlinks.read` | Getting the payment links and it's corresponding payments |
| `paymentlinks.write` | Creating new payment links and being able to close existing once |
| `subscription.read` | Getting the subscriptions in MijnKlantportaal |
| `subscription.write` | Creating, editing and deleting subscriptions in MijnKlantportaal |
| `tickets.read` | Getting and reading support tickets |
| `tickets.write` | Being able to respond to support tickets and close them (marking as done) |
| `webhooks.read` | Listing and getting the webhooks which are created and set up |
| `webhooks.write` | Creating new webhooks and being able to delete existing once |