Getting Started

Authentication, base URL, rate limiting, and how to use this documentation.

Written by Exportlab · Updated March 2026

Overview

Public REST API for integrating HR, CRM, or ERP systems with exportlab.io group shoot galleries, plus public endpoints for custom check-in flows.

List participants and retrieve their assigned photos, all scoped to your tenant.

Base URL

text
Copied
https://api.exportlab.io/v1

Authentication

Every request requires two headers.

Get your API key in the exportlab.io admin under Settings → Integration → API Keys.

Go to Settings → Integration, scroll to the API Keys section, click New key, give it a name (example: HR Integration), and copy the key immediately. It is only shown once.

The API is designed for server-to-server use. Never expose your API key in a browser or client-side code.

Public check-in frontend endpoints (GET /group-shoot/checkin/{token} and POST /group-shoot) do not require an API key, but they still require a valid tenant slug.

Server-side Group Shoot API endpoints, such as listing persons, importing persons, photos, form fields, shooting days, and stats, require both tenant slug and API key and are available on Creator and higher plans.

bash
Copied
curl -X GET "https://api.exportlab.io/v1/group-shoot/checkin/{TOKEN}" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "X-Tenant-Slug: YOUR_TENANT"
HeaderDescription
Authorization: Bearer Your API key. Also accepted as X-Api-Key:
X-Tenant-Slug: Your tenant identifier (example: acme)

Response format

All responses are JSON.

The X-Request-Id response header contains the same request ID. Include it in support requests.

json
Copied
{
  "ok": true,
  "requestId": "6322678e-7898-43eb-baeb-5de42b07ca7f"
}

Rate limiting

The API enforces a limit of 60 requests per minute per API key. If you exceed the limit you receive a 429 response.

Wait until X-RateLimit-Reset before retrying. For bulk imports, add a small delay between requests to stay within the limit.

json
Copied
{
  "ok": false,
  "error": "rate_limit_exceeded",
  "message": "Rate limit exceeded. Max 60 requests per minute. Retry after 42s.",
  "requestId": "..."
}
HeaderDescription
X-RateLimit-LimitMax requests allowed per window (60)
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp (seconds) when the window resets

Error codes

HTTPerrorDescription
400missing_tenant_slugX-Tenant-Slug header is missing
400invalid_tenantTenant slug could not be resolved
400not_a_groupshoot_galleryThe gallery token exists but is not a group shoot
400token_requiredGallery token is missing
400name_requiredName is missing or empty
400email_requiredEmail is missing or empty in the check-in submission
400terms_not_acceptedA paid package was selected but package terms were not accepted
400connect_not_ready_for_paymentsStripe Connect is not ready for package checkout
400payment_access_not_approvedSeller Verification or package payment access is not approved
400package_amount_exceeds_limitSelected paid package exceeds the allowed transaction limit
400invalid_jsonRequest body is not valid JSON
401api_key_requiredNo API key provided
401invalid_api_keyAPI key is wrong, revoked, or disabled
404gallery_not_foundGallery token does not exist
404person_not_foundPerson ID does not exist in this gallery
400persons_requiredPOST /persons called with an empty or missing persons array
400too_many_personsMore than 500 persons in a single import request
403plan_upgrade_requiredTenant is not on Creator plan or above
405method_not_allowedWrong HTTP method for this endpoint (POST /persons is the only non-GET endpoint)
409shooting_day_fullThe selected shooting day has reached its configured capacity
429rate_limit_exceededToo many requests. See X-RateLimit-Reset header
500cdn_signing_unavailableCloudFront signing failed — retry the request
500internal_errorServer error, contact support with the requestId
503plan_check_unavailableCould not verify plan eligibility — retry the request

URL aliases

Both URL patterns are equivalent and fully supported.

MethodPatternDescription
GET/group-shoot/checkin/{token}/form-fieldsPrimary
GET/groupshoot/{token}/form-fieldsShort alias
GET/group-shoot/checkin/{token}/daysPrimary
GET/groupshoot/{token}/daysShort alias
GET/group-shoot/checkin/{token}/statsPrimary
GET/groupshoot/{token}/statsShort alias
GET/group-shoot/checkin/{token}/personsPrimary
GET/groupshoot/{token}/personsShort alias
POST/group-shoot/checkin/{token}/personsPrimary (import)
POST/groupshoot/{token}/personsShort alias (import)
GET/group-shoot/checkin/{token}/persons/{personId}/photosPrimary
GET/groupshoot/{token}/persons/{personId}/photosShort alias