Every Blueport API.
One page for every Blueport product you can integrate with: hosts, authentication, endpoints, request and response shapes, errors and billing.
All products
| Product | API | Host | Auth |
|---|---|---|---|
| PDF2JSON | Public | api.blueport.io/v1/pdf2json | Organisation key |
| HTML2PDF | Public | api.blueport.io/v1/html2pdf | Organisation key |
| VECTOR | Tracker | app.blueport.io | Site key |
| Email archive (MAS) | Enterprise | mas.blueport.io | Client credentials |
| PURL | Enterprise | api.purl.id/v1 | Domain + key |
| DOCGEN, BETSTOP, CRYSTAL, PORTIA | No public API | n/a | n/a |
When you are ready to make calls: Public APIs are self-serve, so subscribe at app.blueport.io and your key is issued straight away. Enterprise APIs are set up with you during onboarding, and Blueport issues their credentials then. Until then, everything on this page is yours to read.
Conventions (PDF2JSON and HTML2PDF)
• Auth: send your organisation key in the x-api-key header (?api_key= also works but leaks into logs; prefer the header). The same key covers PDF2JSON and HTML2PDF. Admins view the masked key and rotate it at app.blueport.io; rotation invalidates the old key immediately.
• Responses: JSON responses are {"ok": true, "data", "meta"}. Every response carries a request_id, in the body or the x-request-id header. Quote it when you contact support.
• Errors: {"ok": false, "error", "request_id"}. 401 means a missing or bad key, 400 bad input, 413 too large, 404 an unknown route. Retry 5xx with backoff.
• Billing: both products draw from the one Blueport API credit pool. Each response reports billed_units and credits. Failed calls are never billed.
• Privacy: payloads are processed in flight and not stored. Only usage counts and timings are recorded.
PDF2JSON Public
PDF in, clean JSON out. Semantic extraction of invoices, contracts and forms with typed values and grouped entities, and no templates to maintain.
Endpoints
/v1/pdf2jsonExtract a PDF to JSON. Needs a key./v1/pdf2json/profilesList the built-in output profiles. Add ?schema=1 for each profile's JSON Schema. No key needed.Request
Send the PDF one of two ways (multipart uploads are not accepted, and the limit is 8 MB):
# 1. raw PDF body curl https://api.blueport.io/v1/pdf2json \ -H "x-api-key: $BLUEPORT_KEY" \ -H "content-type: application/pdf" \ --data-binary @invoice.pdf # 2. JSON with a base64 PDF curl https://api.blueport.io/v1/pdf2json \ -H "x-api-key: $BLUEPORT_KEY" \ -H "content-type: application/json" \ -d '{"pdf": "JVBERi0xLjQK...", "document_type": "vehicle_tax_invoice"}'
| Field | Description |
|---|---|
| pdf / pdf_base64 | The PDF as base64 (JSON requests). |
| document_type | Optional profile id; the x-document-type header works for either request style. Leave it out and the document is classified for you. |
| schema | Optional JSON Schema object for your own output shape. The response then reports document_type: "custom". |
Built-in profiles: vehicle_sale_contract, vehicle_tax_invoice, nsw_form7_dealer_notice, nsw_registration_application, generic_document.
Response
{
"ok": true,
"data": { /* extracted fields, in the profile's shape */ },
"meta": {
"request_id": "req_…", "duration_ms": 5210,
"pages": 2, "billed_units": 1, "credits": 10,
"document_type": "vehicle_tax_invoice", "profile_version": 2,
"warnings": []
}
}
Errors
| Status | Meaning |
|---|---|
| 400 | No PDF in the request, the body is not a PDF, schema is not an object, or document_type is unknown. |
| 401 | Missing or invalid key. |
| 413 | PDF larger than 8 MB. |
| 422 | The document could not be processed (refused). |
| 502 | Extraction returned unusable output (bad_output). Safe to retry. |
| 500 | Unexpected error. Retry with backoff. |
Billing
1 billed unit = one document of up to 5 pages (a 12-page PDF is 3 units). Each unit is 10 credits. Failed calls bill 0.
HTML2PDF Public
HTML in, pixel-perfect PDF out, rendered by a real browser engine. Send raw HTML, an inline template with data, or the id of a stored template.
Endpoints
/v1/html2pdfRender a PDF./v1/html2pdf/templatesCreate a template from {name, html}. Returns 201./v1/html2pdf/templatesList your templates./v1/html2pdf/templates/{id}Get one template. ?version=n for an older version./v1/html2pdf/templates/{id}Save {html?, name?} as a new version. Earlier versions stay unchanged./v1/html2pdf/templates/{id}Delete a template./v1/html2pdf/templates/{id}/previewFree render with {data?, options?, template_version?}. Returns base64 by default.Three ways to render
# 1. raw HTML curl https://api.blueport.io/v1/html2pdf \ -H "x-api-key: $BLUEPORT_KEY" -H "content-type: text/html" \ --data-binary @statement.html -o statement.pdf # 2. inline template + data (Handlebars) -d '{"html": "<h1>Hi {{name}}</h1>", "data": {"name": "Sam"}, "options": {"size": "A4"}}' # 3. stored template -d '{"template_id": "tpl_…", "template_version": 3, "data": {…}}'
html and template_id cannot be sent together. Templates support the helpers formatCurrency and formatDate.
Options
| Option | Description |
|---|---|
| size | A4 (default), A3, A5, Letter, Legal, Tabloid, or {width, height}. |
| landscape | Boolean, default false. |
| printBackground | Boolean, default true. |
| margin | A CSS length or {top, right, bottom, left}. Default 14 / 14 / 16 / 14 mm. |
| header / footer | HTML repeated on every page. {{page}} and {{pages}} become page numbers. |
| scale | 0.1 to 2. |
| filename | Name in content-disposition. Also ?filename=. |
Response
By default you get the PDF bytes, with headers x-request-id, x-pages, x-billed-units and x-credits. Add ?output=base64 (or "output": "base64") for JSON:
{ "ok": true,
"data": { "pdf": "JVBERi0…", "pages": 3, "filename": "statement.pdf" },
"meta": { "request_id": "req_…", "pages": 3, "billed_units": 1, "credits": 1 } }
Errors
| Status | Meaning |
|---|---|
| 400 | Empty HTML, invalid JSON, both or neither of html / template_id, a template merge error, or an invalid option. |
| 401 | Missing or invalid key. |
| 404 | Template or template version not found. |
| 409 | Template limit reached (100 per organisation). |
| 413 | Request body over 2 MB, or template HTML over 512 KB. |
| 500 | Unexpected error. Retry with backoff. |
Billing
1 billed unit = one render of up to 20 pages. Each unit is 1 credit. Previews, template management and failed renders are free.
VECTOR Tracker
VECTOR turns website behaviour into affinities and next-best actions in Salesforce. The public integration is the browser tracker. Affinities, actions and the Salesforce sync are configured in the portal at app.blueport.io, not through an API.
Install
Paste this before </body> on every page. Your site key (vk_…) is on the VECTOR setup screen in the portal.
<script>window.BlueportVector = { k: "vk_your_site_key" };</script>
<script async src="https://app.blueport.io/v.js"></script>
Page views are tracked automatically. From your own code:
BlueportVector.track("brochure_download"); // custom event BlueportVector.identify("sam@example.com"); // link the visitor to a known contact
Endpoints
https://app.blueport.io/v.jsThe tracker script.https://app.blueport.io/collectEvent intake, called by the tracker. You only need it for server-side events.| Field | Description |
|---|---|
| k | Site key (required). |
| vid | Visitor id (bpv_…), set by the tracker. |
| e | Event name. Default pageview. |
| u, t, r | Page URL, page title, referrer. |
| em | Email, sent after identify(). |
| ts, lang, tz, sw, sh | Timestamp, language, time zone, screen width and height. |
/collect always answers 200 {"ok": true}, even for an invalid key, so the tracker never breaks your page. Check events arrive on the VECTOR screen in the portal. Each site key accepts up to 36,000 events an hour; events over that are dropped. Events are kept for 90 days.Email archive (MAS) Enterprise
Every email sent from Marketing Cloud is archived as a PDF against the subscriber. Your systems (a contact centre, a customer portal) can list a subscriber's archived emails and fetch each PDF. Your client_id and client_secret are issued when the archive is set up for you.
Endpoints
https://mas.blueport.io/authExchange client credentials for an access token.https://mas.blueport.io/files/subscriber/{subscriber_key}List a subscriber's archived emails, newest first.https://mas.blueport.io/files/v2/id/{id}Download one archived email as a PDF.1. Get a token
curl https://mas.blueport.io/auth \ -H "content-type: application/json" \ -d '{"client_id": "…", "client_secret": "…"}' { "access_token": "eyJ…", "expires_in": 3600 }
Tokens last one hour. Send them as Authorization: Bearer <token>.
2. List a subscriber's emails
curl "https://mas.blueport.io/files/subscriber/0035g00000AbCdE?page_size=50" \ -H "Authorization: Bearer $TOKEN" { "items": [ { "bp_file_key": "…", "bp_date_sent": "2026-10-14T09:12:00Z", "bp_signed_url": "https://…", "mc_*": "send attributes…" } ], "next": "…" }
Paging: page_num and page_size (default 1000); follow next / prev. bp_signed_url is a short-lived direct download link.
Errors
| Status | Meaning |
|---|---|
| 400 | Invalid JSON or parameters. |
| 401 | Bad or inactive credentials, or a missing or expired token. |
| 404 | File not found. |
| 503 | Temporarily unavailable. Retry after the Retry-After header. |
Archiving itself needs no code from you: Blueport connects your Marketing Cloud account to the archive during onboarding.
PURL Enterprise
Personalised short links for Marketing Cloud sends, on purl.id or your own branded domain. Each subscriber gets a stable short link per long URL, so clicks are attributed to the person. Your domain and API key are issued during onboarding.
Endpoint
https://api.purl.id/v1/shortenCreate or return the short link for a subscriber and URL.All inputs are sent as request headers, which suits AMPscript HTTPPost:
| Header | Description |
|---|---|
| domain | Your short-link domain (required). |
| api_key | Your PURL key (required). |
| long_url | The destination URL (required). |
| subscriber_key | The Marketing Cloud subscriber key (required). |
| utm_*, mc_* | Optional tracking values, stored with the link as sent. |
curl -X POST https://api.purl.id/v1/shorten \ -H "domain: go.example.com" -H "api_key: $PURL_KEY" \ -H "long_url: https://example.com/offer" -H "subscriber_key: 0035g00000AbCdE" https://go.example.com/aB3dE9x
The response is the short URL as plain text. The same long_url and subscriber_key always return the same link.
Errors
| Status | Meaning |
|---|---|
| 400 | Missing domain, long_url or subscriber_key. |
| 401 | Invalid key for this domain. |
| 404 | Unable to process your request. Any other failure; retry once, then contact support. |
Products without a public API Portal & managed
| Product | How you use it |
|---|---|
| DOCGEN | Document generation built into your Marketing Cloud sends. Set up and run by Blueport for each customer. |
| BETSTOP | A Journey Builder activity that checks the National Self-Exclusion Register before each send. You add it to a journey; there is nothing to call. |
| CRYSTAL | Salesforce org health scans, run from the portal at app.blueport.io. |
| PORTIA | Blueport's AI agents, delivered as a managed service. |
Need programmatic access to any of these? Tell us what you are building.
Support
Person-to-person, included with every plan: portia@blueport.io. Include the request_id from the response. Keys, usage and billing live at app.blueport.io.