# 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 |