Formulieren
Uploads
Sla vanaf je server een bestand van een bezoeker op voor een bestandsveld van een formulier en krijg een token voor eenmalig gebruik om met de inzending mee te sturen.
Bekijk als MarkdownEen file-veld beantwoord je met uploadtokens. Upload eerst elk bestand dat de bezoeker kiest en stuur de tokens daarna mee in het object files van de inzending (zie Inzendingen). Net als inzendingen hebben uploads een forms:write-sleutel nodig, dus verstuur ze vanaf je server, nooit vanuit de browser (zie Houd forms:write-sleutels op je server).
Een file-veld beantwoord je met uploadtokens. Upload eerst elk bestand dat de bezoeker kiest en stuur de tokens daarna mee in het object files van de inzending (zie Inzendingen). Net als inzendingen hebben uploads een forms:write-sleutel nodig, dus verstuur ze vanaf je server, nooit vanuit de browser (zie Houd forms:write-sleutels op je server).
POST /v1/api/forms/{key}/uploads
Slaat één bestand op voor één file-veld van de gepubliceerde versie van het formulier en geeft er een token voor terug. Vereist de scope forms:write. Het formulier moet actief en gepubliceerd zijn.
Het bestand wordt privé opgeslagen: het heeft geen publieke URL, en de merchant opent het vanuit de inbox in het dashboard zodra een inzending het claimt.
Padparameters
| Naam | Type | Verplicht | Beschrijving |
|---|---|---|---|
key | string | Ja | De key van het formulier, bijvoorbeeld quote-request. |
Headers
| Naam | Type | Verplicht | Beschrijving |
|---|---|---|---|
Authorization | string | Ja | Bearer {forms_write_key}. |
Content-Type | string | Ja | multipart/form-data (je HTTP-client zet dit als je form data verstuurt). |
X-Borkol-Visitor-Ip | string | Nee | Het IP-adres van de bezoeker (IPv4 of IPv6). De uploadlimiet telt per bezoekersadres. Ontbreekt hij of is het geen geldig IP-adres, dan wordt het adres van de verbinding (je server) gebruikt. Zie Bezoekers-IP en de limiet per uur. |
Bodyparameters
Verstuur de body als multipart/form-data.
| Naam | Type | Verplicht | Beschrijving |
|---|---|---|---|
field | string | Ja | De key van een file-veld in de gepubliceerde versie van het formulier, maximaal 64 tekens. |
file | file | Ja | Eén bestand. Het type wordt bepaald aan de hand van de inhoud, niet van de naam of het Content-Type dat de browser stuurde, en moet passen bij accept van het veld: image laat JPEG, PNG, WebP en HEIC/HEIF door; pdf laat PDF door. SVG en elk ander type worden geweigerd. Maximaal max_mb van het veld (1 tot 20 MB). |
Status: 201 Created. Het resultaat is verpakt in data.
| Naam | Type | Verplicht | Beschrijving |
|---|---|---|---|
token | string (UUID) | altijd | Stuur het mee in files van de inzending, onder dezelfde veld-key. |
name | string | altijd | De opgeslagen bestandsnaam: de bestandsnaam van de bezoeker zonder pad of stuurtekens, maximaal 150 tekens vóór de extensie, met de extensie die de inhoud bewijst (jpg, png, webp, heic of pdf). file als er van de naam niets overblijft. |
size | integer | altijd | De bestandsgrootte in bytes. |
Tokens
- Een token hoort bij het formulier en het veld waarvoor het is geüpload. Stuur je het mee voor een ander formulier of een ander veld, dan antwoordt de inzending
422opfiles.{key}. - Een token werkt voor één inzending. Een inzending die wordt geweigerd (elke
422) claimt niets, dus dezelfde tokens kun je opnieuw meesturen met de verbeterde inzending. - Een token verloopt 24 uur na de upload. Een verlopen token geeft
422opfiles.{key}; upload het bestand dan opnieuw. Bestanden die geen inzending heeft geclaimd, worden verwijderd zodra hun token is verlopen. - Upload één bestand per request. Voor een veld met
max_filesboven 1 upload je elk bestand apart en stuur je alle tokens mee in één lijst, maximaalmax_files. - De upload kijkt niet naar de regels van het formulier: of het veld wordt getoond, wordt bepaald wanneer de inzending binnenkomt. Tokens voor een veld dat op dat moment verborgen is, worden genegeerd en verlopen ongebruikt.
Uploadlimiet
Elk formulier accepteert 30 uploads per bezoeker per uur, geteld per bezoekersadres uit X-Borkol-Visitor-Ip, los van de limiet voor inzendingen. Elke poging telt, ook uploads die met 422 stranden. Boven de limiet:
De response heeft status 429 en geen Retry-After-header. De winkelbrede limiet van 120 requests per minuut geldt ook (zie Errors en rate limits).
Fouten
422 validatie. De standaard envelope (zie Errors en rate limits):
| Key | Melding | Wanneer |
|---|---|---|
field | De standaardmeldingen van Laravel | Ontbreekt, is geen string of is langer dan 64 tekens. |
field | Not a file field of this form. | Geen file-veld met die key in de gepubliceerde versie. |
file | De standaardmeldingen van Laravel | Ontbreekt, is geen geüpload bestand of is groter dan 20 MB. |
file | The file may not be larger than {max} MB. | Groter dan max_mb van het veld. |
file | This file type is not accepted here. | De inhoud is geen type dat accept van het veld toestaat. |
Andere fouten.
404als geen formulier van de winkel deze key heeft, of als het een concept is, gearchiveerd, nooit gepubliceerd of verwijderd.403{"error":"Module not enabled: forms"}als de module forms uit staat voor de winkel, en403{"message":"Invalid ability provided."}als de sleutelforms:writemist.401zoals op elke/v1/api-route.
curl -X POST "https://api.borkol.com/v1/api/forms/quote-request/uploads" \
-H "Authorization: Bearer {forms_write_key}" \
-H "Accept: application/json" \
-H "X-Borkol-Visitor-Ip: 203.0.113.24" \
-F "field=brief" \
-F "file=@brief.pdf"// A Next.js route handler: the browser posts multipart (field, file) here, never to Borkol.
export async function POST(request) {
// Only trust an IP header your own proxy or host sets.
const visitorIp = request.headers.get("x-real-ip") ?? "";
const res = await fetch("https://api.borkol.com/v1/api/forms/quote-request/uploads", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BORKOL_FORMS_KEY}`,
Accept: "application/json",
"X-Borkol-Visitor-Ip": visitorIp,
},
body: await request.formData(),
});
return new Response(res.body, { status: res.status, headers: { "Content-Type": "application/json" } });
}{
"data": {
"token": "9b2f0c3e-5a1d-4f7e-8c2b-1d3e4f5a6b7c",
"name": "brief.pdf",
"size": 482113
}
}{
"message": "Too many uploads. Try again later."
}{
"message": "This file type is not accepted here.",
"errors": {
"file": ["This file type is not accepted here."]
}
}POST /v1/api/forms/{key}/uploads
Slaat één bestand op voor één file-veld van de gepubliceerde versie van het formulier en geeft er een token voor terug. Vereist de scope forms:write. Het formulier moet actief en gepubliceerd zijn.
Het bestand wordt privé opgeslagen: het heeft geen publieke URL, en de merchant opent het vanuit de inbox in het dashboard zodra een inzending het claimt.
Padparameters
| Naam | Type | Verplicht | Beschrijving |
|---|---|---|---|
key | string | Ja | De key van het formulier, bijvoorbeeld quote-request. |
Headers
| Naam | Type | Verplicht | Beschrijving |
|---|---|---|---|
Authorization | string | Ja | Bearer {forms_write_key}. |
Content-Type | string | Ja | multipart/form-data (je HTTP-client zet dit als je form data verstuurt). |
X-Borkol-Visitor-Ip | string | Nee | Het IP-adres van de bezoeker (IPv4 of IPv6). De uploadlimiet telt per bezoekersadres. Ontbreekt hij of is het geen geldig IP-adres, dan wordt het adres van de verbinding (je server) gebruikt. Zie Bezoekers-IP en de limiet per uur. |
Bodyparameters
Verstuur de body als multipart/form-data.
| Naam | Type | Verplicht | Beschrijving |
|---|---|---|---|
field | string | Ja | De key van een file-veld in de gepubliceerde versie van het formulier, maximaal 64 tekens. |
file | file | Ja | Eén bestand. Het type wordt bepaald aan de hand van de inhoud, niet van de naam of het Content-Type dat de browser stuurde, en moet passen bij accept van het veld: image laat JPEG, PNG, WebP en HEIC/HEIF door; pdf laat PDF door. SVG en elk ander type worden geweigerd. Maximaal max_mb van het veld (1 tot 20 MB). |
curl -X POST "https://api.borkol.com/v1/api/forms/quote-request/uploads" \
-H "Authorization: Bearer {forms_write_key}" \
-H "Accept: application/json" \
-H "X-Borkol-Visitor-Ip: 203.0.113.24" \
-F "field=brief" \
-F "file=@brief.pdf"// A Next.js route handler: the browser posts multipart (field, file) here, never to Borkol.
export async function POST(request) {
// Only trust an IP header your own proxy or host sets.
const visitorIp = request.headers.get("x-real-ip") ?? "";
const res = await fetch("https://api.borkol.com/v1/api/forms/quote-request/uploads", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BORKOL_FORMS_KEY}`,
Accept: "application/json",
"X-Borkol-Visitor-Ip": visitorIp,
},
body: await request.formData(),
});
return new Response(res.body, { status: res.status, headers: { "Content-Type": "application/json" } });
}Status: 201 Created. Het resultaat is verpakt in data.
| Naam | Type | Verplicht | Beschrijving |
|---|---|---|---|
token | string (UUID) | altijd | Stuur het mee in files van de inzending, onder dezelfde veld-key. |
name | string | altijd | De opgeslagen bestandsnaam: de bestandsnaam van de bezoeker zonder pad of stuurtekens, maximaal 150 tekens vóór de extensie, met de extensie die de inhoud bewijst (jpg, png, webp, heic of pdf). file als er van de naam niets overblijft. |
size | integer | altijd | De bestandsgrootte in bytes. |
{
"data": {
"token": "9b2f0c3e-5a1d-4f7e-8c2b-1d3e4f5a6b7c",
"name": "brief.pdf",
"size": 482113
}
}Tokens
- Een token hoort bij het formulier en het veld waarvoor het is geüpload. Stuur je het mee voor een ander formulier of een ander veld, dan antwoordt de inzending
422opfiles.{key}. - Een token werkt voor één inzending. Een inzending die wordt geweigerd (elke
422) claimt niets, dus dezelfde tokens kun je opnieuw meesturen met de verbeterde inzending. - Een token verloopt 24 uur na de upload. Een verlopen token geeft
422opfiles.{key}; upload het bestand dan opnieuw. Bestanden die geen inzending heeft geclaimd, worden verwijderd zodra hun token is verlopen. - Upload één bestand per request. Voor een veld met
max_filesboven 1 upload je elk bestand apart en stuur je alle tokens mee in één lijst, maximaalmax_files. - De upload kijkt niet naar de regels van het formulier: of het veld wordt getoond, wordt bepaald wanneer de inzending binnenkomt. Tokens voor een veld dat op dat moment verborgen is, worden genegeerd en verlopen ongebruikt.
Uploadlimiet
Elk formulier accepteert 30 uploads per bezoeker per uur, geteld per bezoekersadres uit X-Borkol-Visitor-Ip, los van de limiet voor inzendingen. Elke poging telt, ook uploads die met 422 stranden. Boven de limiet:
{
"message": "Too many uploads. Try again later."
}De response heeft status 429 en geen Retry-After-header. De winkelbrede limiet van 120 requests per minuut geldt ook (zie Errors en rate limits).
Fouten
422 validatie. De standaard envelope (zie Errors en rate limits):
| Key | Melding | Wanneer |
|---|---|---|
field | De standaardmeldingen van Laravel | Ontbreekt, is geen string of is langer dan 64 tekens. |
field | Not a file field of this form. | Geen file-veld met die key in de gepubliceerde versie. |
file | De standaardmeldingen van Laravel | Ontbreekt, is geen geüpload bestand of is groter dan 20 MB. |
file | The file may not be larger than {max} MB. | Groter dan max_mb van het veld. |
file | This file type is not accepted here. | De inhoud is geen type dat accept van het veld toestaat. |
{
"message": "This file type is not accepted here.",
"errors": {
"file": ["This file type is not accepted here."]
}
}Andere fouten.
404als geen formulier van de winkel deze key heeft, of als het een concept is, gearchiveerd, nooit gepubliceerd of verwijderd.403{"error":"Module not enabled: forms"}als de module forms uit staat voor de winkel, en403{"message":"Invalid ability provided."}als de sleutelforms:writemist.401zoals op elke/v1/api-route.