Geo Insights Back to homepage

API Documentation

The Geo Insights marketing website exposes two public API endpoints for contact form submission and newsletter signup. Both endpoints accept JSON and return JSON responses.

Base URL

https://geo-insights.nl

All endpoints use HTTPS. Requests must include a Content-Type: application/json header. No authentication is required.

Rate Limiting

All API endpoints are rate limited per IP address. When a rate limit is exceeded, the API returns a 429 Too Many Requests response with the following headers:

HeaderDescription
Retry-AfterSeconds until the rate limit resets
RateLimit-LimitMaximum requests allowed in the window
RateLimit-RemainingRequests remaining in the current window
RateLimit-ResetSeconds until the current window resets
RateLimit-PolicyRate limit policy description (e.g. 5;w=600)

Error Responses

All errors return a JSON object with an error code, a human-readable message, and a resolution hint:

{
  "error": "MISSING_REQUIRED_FIELDS",
  "message": "Missing required fields",
  "resolution": "Provide name, organization, email and message in the JSON body."
}

POST /api/contact

POST Submit a contact form inquiry. Rate limited to 5 requests per 10 minutes per IP.

Request Body

FieldTypeRequiredDescription
namestringrequiredFull name (max 200 chars)
organizationstringrequiredOrganization name (max 200 chars)
emailstringrequiredContact email address
messagestringrequiredMessage body (max 5000 chars)
topicstringoptionalSubject or topic of the inquiry

Example Request

curl -X POST https://geo-insights.nl/api/contact \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Jan de Vries",
    "organization": "Gemeente Rotterdam",
    "email": "[email protected]",
    "topic": "pilot",
    "message": "Wij zijn geïnteresseerd in een pilot."
  }'

Success Response

HTTP/1.1 200 OK
Content-Type: application/json

{ "ok": true }

Error Codes

CodeStatusMeaning
METHOD_NOT_ALLOWED405Only POST is accepted
INVALID_BODY400Request body is not valid JSON
MISSING_REQUIRED_FIELDS400name, organization, email or message is missing
INVALID_EMAIL400Email format is invalid
FIELD_TOO_LONG400A field exceeds its maximum length
RATE_LIMITED429Too many requests — wait and retry
SERVER_NOT_CONFIGURED500SMTP credentials not set
SERVER_ERROR500Unexpected server error

POST /api/newsletter

POST Subscribe to pilot update emails. Rate limited to 10 requests per 10 minutes per IP.

Request Body

FieldTypeRequiredDescription
emailstringrequiredEmail address to subscribe
firstNamestringoptionalFirst name (max 80 chars)
lastNamestringoptionalLast name (max 80 chars)

Example Request

curl -X POST https://geo-insights.nl/api/newsletter \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "firstName": "Jan",
    "lastName": "de Vries"
  }'

Success Response

HTTP/1.1 200 OK
Content-Type: application/json

{ "ok": true }

Error Codes

CodeStatusMeaning
METHOD_NOT_ALLOWED405Only POST is accepted
INVALID_BODY400Request body is not valid JSON
MISSING_EMAIL400Email field is missing
INVALID_EMAIL400Email format is invalid
RATE_LIMITED429Too many requests — wait and retry
SERVER_NOT_CONFIGURED500Mailchimp credentials not set
UPSTREAM_ERROR502Mailchimp returned an error
SERVER_ERROR500Unexpected server error

Content Negotiation

The homepage supports Markdown content negotiation per the acceptmarkdown.com specification. Send Accept: text/markdown to receive a Markdown representation of the homepage content:

curl -H "Accept: text/markdown" https://geo-insights.nl/

The response includes Content-Type: text/markdown and Vary: Accept headers. Standard Accept: text/html requests return the full HTML page as usual.

Machine-Readable Resources