Overview
The VisitSign API is intended for server-to-server integrations where protected resources are accessed using a static bearer token through the HTTP Authorization header.
Each integration is assigned a unique bearer token. That token is stored server-side by the customer and sent with every request to protected endpoints.
Since one customer may have multiple pages, there is a protected endpoint for listing available pages and their page_id values before validation requests are made.
The API includes public endpoints for health checks and version information, as well as protected endpoints for page listing and registration validation.
Capabilities
- List all available pages for the authenticated customer through
GET /pages. - Return
page_id,page_hid,page_name, BankID support and linked domains per page. - Validate a registration using
page_id,customer_idandverification_id. - Return identity data only when the registration is valid.
- Expose health information for monitoring and operational checks.
- Expose version and build information for diagnostics and release verification.
- Return consistent machine-readable error codes for failed requests.
Quick start
- Store the assigned bearer token on the server side in the integration environment.
- Send the token in the header
Authorization: Bearer <token>when calling protected endpoints. - Call
GET /pagesto retrieve the customer’s available pages and the correctpage_id. - Call
POST /statuswithpage_id,customer_idandverification_idto validate a registration. - Use
GET /healthfor monitoring andGET /versionfor diagnostics and release verification. - If token leakage is suspected or rotation is required, a new token must be issued administratively and the previous token must stop being used immediately.
Authentication
Protected endpoints accept bearer tokens only.
The required format is Authorization: Bearer <token>.
Each integration is assigned a unique static bearer token that is used directly against protected endpoints.
The token must be treated as a secret, handled server-side only, and never exposed in frontend code, mobile apps or public client applications.
The following endpoints require a bearer token: GET /pages and POST /status.
The following endpoints are public: GET /health and GET /version.
Token issuance, revocation and rotation are handled outside this public API.
Authorization: Bearer vs_live_4f9348d31cf54b3ea8c12d1cfab0ce42
Headers
Standard headers used by the API.
| Header | Required | Description |
|---|---|---|
Authorization |
For protected endpoints | Bearer token for protected endpoints. Format: Bearer <token>. |
Content-Type: application/json |
For JSON body | Must be sent when the request body contains JSON. |
Accept: application/json |
No | Recommended to explicitly request JSON responses. |
Endpoints
| Method | Endpoint | Authentication | Purpose |
|---|---|---|---|
| GET | /pages |
Bearer | Lists the customer’s available pages and their page_id values. |
| POST | /status |
Bearer | Validates a registration for a specific page. |
| GET | /health |
Public | Returns service health status. |
| GET | /version |
Public | Returns API version and build information. |
GET /pages
Lists all pages belonging to the authenticated customer linked to the bearer token.
- This endpoint requires a bearer token.
- It is used to retrieve the correct
page_idbefore validation requests are made. - Each page may have one or more linked domains.
{
"status": "ok",
"pages": [
{
"page_id": 101,
"page_hid": "c0a4d62f9ddf4a5f8c2c3e7d1f9a0b11c2d3e4f5",
"page_name": "Exempelbolaget Downhill AB",
"use_bankid": true,
"domains": [
"exempelbolaget-downhill.visitsign.se"
]
},
{
"page_id": 102,
"page_hid": "f7b2a1c4836d4b0c8f31d9e8a4c2b6d7e9f0a1b2",
"page_name": "Exempelbolaget Event AB",
"use_bankid": true,
"domains": [
"exempelbolaget-event.visitsign.se"
]
}
]
}
Fields
| Field | Type | Description |
|---|---|---|
page_id |
integer | Internt sid-ID som används i sidspecifika anrop. |
page_hid |
string | Publikt eller externt sid-ID. |
page_name |
string | Sidans namn. |
use_bankid |
boolean | Anger om sidan använder BankID. |
domains |
array | Lista över domäner kopplade till sidan. |
POST /status
Validates a registration using page_id, customer_id and verification_id.
- This endpoint requires a bearer token.
page_idmust belong to the customer linked to the token.- Returns
status: "valid"orstatus: "invalid". - Identity fields are returned only when the registration is valid.
{
"page_id": 101,
"customer_id": "EXEMPEL-1",
"verification_id": "VERIFY-1001"
}
{
"status": "valid",
"givenname": "Anna",
"surname": "Exempelsson",
"ssn": "19980512-1234",
"valid_until": "2026-11-02"
}
{
"status": "invalid"
}
{
"status": "invalid",
"reason": "expired"
}
Fields
| Field | Type | Description |
|---|---|---|
page_id |
integer | Obligatoriskt sid-ID för den sida som valideringen avser. |
customer_id |
string | Unikt kund-ID. |
verification_id |
string | Verifikations-ID för registreringen. |
GET /health
Returns the service health status.
- This endpoint is public.
- Can be used for monitoring and operational checks.
{
"status": "ok",
"service": "visitsign-api",
"timestamp": "2026-04-15T12:00:00Z"
}
GET /version
Returns version and build information for the current deployment.
- This endpoint is public.
- Can be used for diagnostics, operations and release verification.
{
"status": "ok",
"version": "v1",
"build": "2026-04-15"
}
Responses & semantics
All successful responses are returned as JSON with Content-Type: application/json; charset=utf-8.
valid: the registration exists and is valid for current use.invalid: the registration exists but is not valid for current use.invalid+reason: "expired": the registration exists but has expired.ok: the endpoint completed successfully.pages: list of pages belonging to the customer.not_found: no registration matched the supplied identifiers.
{
"status": "error",
"error_code": "missing_page_id",
"message": "No page_id supplied."
}
Error codes
Error responses are returned as JSON with a machine-readable error code and message.
| Error code | HTTP status | Description |
|---|---|---|
invalid_endpoint |
404 | The requested endpoint does not exist. |
invalid_method |
405 | The HTTP method is not allowed for the endpoint. |
invalid_payload |
400 | The request body contains invalid JSON. |
missing_token |
401 | No bearer token was supplied. |
invalid_token |
401 | The supplied bearer token is invalid. |
expired_token |
401 | The supplied bearer token has expired. |
revoked_token |
401 | The supplied bearer token has been revoked. |
missing_page_id |
400 | The page_id field is missing. |
invalid_page_id |
404 | The supplied page_id does not exist. |
forbidden_page |
403 | The supplied page_id does not belong to the authenticated customer. |
missing_customer_id |
400 | The customer_id field is missing. |
missing_verification_id |
400 | The verification_id field is missing. |
not_found |
404 | No registration matched the supplied identifiers. |
internal_error |
500 | An unexpected internal error occurred. |
Examples
Production-oriented examples for cURL and PHP.
curl -X GET https://api.visitsign.se/v1/pages \
-H "Authorization: Bearer vs_live_4f9348d31cf54b3ea8c12d1cfab0ce42" \
-H "Accept: application/json"
curl -X POST https://api.visitsign.se/v1/status \
-H "Authorization: Bearer vs_live_4f9348d31cf54b3ea8c12d1cfab0ce42" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"page_id": 101,
"customer_id": "EXEMPEL-1",
"verification_id": "VERIFY-1001"
}'
curl -X GET https://api.visitsign.se/v1/health \
-H "Accept: application/json"
curl -X GET https://api.visitsign.se/v1/version \
-H "Accept: application/json"
<?php
$baseUrl = 'https://api.visitsign.se/v1';
$bearerToken = 'vs_live_4f9348d31cf54b3ea8c12d1cfab0ce42';
function apiRequest(string $method, string $url, ?array $payload = null, ?string $bearerToken = null): array
{
$headers = [
'Accept: application/json'
];
if($payload !== null) {
$headers[] = 'Content-Type: application/json';
}
if($bearerToken !== null) {
$headers[] = 'Authorization: Bearer ' . $bearerToken;
}
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_TIMEOUT => 15
]);
if($payload !== null) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
}
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($response === false) {
throw new RuntimeException(curl_error($ch));
}
curl_close($ch);
return [
'http_code' => $httpCode,
'body' => $response,
'json' => json_decode($response, true)
];
}
$pagesResponse = apiRequest('GET', $baseUrl . '/pages', null, $bearerToken);
if(($pagesResponse['json']['status'] ?? null) !== 'ok' || empty($pagesResponse['json']['pages'])) {
throw new RuntimeException('No pages returned from API.');
}
$pageId = $pagesResponse['json']['pages'][0]['page_id'];
$statusResponse = apiRequest('POST', $baseUrl . '/status', [
'page_id' => $pageId,
'customer_id' => 'EXEMPEL-1',
'verification_id' => 'VERIFY-1001'
], $bearerToken);
echo 'HTTP ' . $statusResponse['http_code'] . PHP_EOL;
echo $statusResponse['body'] . PHP_EOL;
Security
- Always use HTTPS.
- Store bearer tokens securely on the server side.
- Never expose the token in frontend code, apps or shared client environments.
- Implement reasonable timeouts, logging and error handling.
- If a token is rotated or revoked, the previous token must stop being used immediately.
Operations
- Monitor
GET /healthcontinuously. - Verify deployment through
GET /versionafter releases. - Check both the HTTP status code and the JSON body in the integration.
- Always retrieve valid
page_idvalues throughGET /pagesbefore validation. - Do not assume a customer has only one page.
Contact
For onboarding, API questions or technical support, contact Sweden Sites AB.
Sweden Sites AB
support@swedensites.com
+46 651 13070