Developers & Integrations

Oakline provides a Public Sessions API allowing tenants to display their session catalogue on external websites or applications. This guide assumes technical knowledge of HTTP APIs.

Overview

The API is read-only and exposes:

  • Session Occurrences: Specific bookable dates and times.
  • Availability: Capacity, remaining spaces, and sold-out status.
  • Tenant Branding: Theme colours for seamless embedding.

[!IMPORTANT] The API does not support booking creation. The checkout must take place on your Oakline portal. All booking_url values in the response link directly to the correct booking page.


Enabling API Access

API access is disabled by default. To enable it:

  1. Contact Oakline support or have a master admin enable it from the platform panel.
  2. Once enabled, your API Key will be visible under Admin > Settings > Integrations.

Authentication

All API requests require an API key passed as a request header:

X-API-Key: oak_your_key_here

Requests without a valid key return 401 Unauthorized. Requests to a tenant with API access disabled return 403 Forbidden.


Base URL

https://oakline.app/api/public/tenants/{tenant_slug}
  • {tenant_slug} — your subdomain identifier (e.g. forestfamilies for forestfamilies.oakline.app).

Both versioned and unversioned paths are supported:

/api/public/tenants/{slug}/sessions      ← current
/api/v1/public/tenants/{slug}/sessions   ← v1 alias (identical)

Endpoints

1. List Sessions

Returns upcoming session occurrences ordered by your custom sort order, then chronologically.

GET /sessions

Query Parameters

Name Type Required Description
from string No Start date YYYY-MM-DD. Defaults to today.
to string No End date YYYY-MM-DD.
limit int No Max results. Default: 500. Max: 1000.
cursor string No Pagination cursor from previous response.

Example Request

GET /api/public/tenants/forestfamilies/sessions?from=2026-04-01&limit=20
X-API-Key: oak_your_key_here

Example Response

{
  "data": [
    {
      "id": 101,
      "template_id": 12,
      "title": "Summer Camp",
      "description": "A full week of outdoor activities...",
      "description_short": "A full week of outdoor activities...",
      "start_at": "2026-06-15T09:00:00",
      "end_at": "2026-06-15T15:00:00",
      "location_name": "Forest Park, Oak Lane",
      "price": {
        "amount": 25.00,
        "currency": "GBP"
      },
      "capacity": {
        "total": 20,
        "remaining": 5,
        "is_full": false
      },
      "age_range": {
        "min": 3,
        "max": 11
      },
      "image_url": "https://...",
      "sort_order": 1,
      "booking_url": "https://forestfamilies.oakline.app/booking?session_id=101"
    }
  ],
  "pagination": {
    "limit": 20,
    "has_more": false,
    "next_cursor": null
  },
  "tenant": {
    "theme_color": "#2C5F2D",
    "secondary_color": "#6c757d",
    "vat_number": "GB123456789"
  }
}

Notes

  • Sessions with is_full: true are still returned — show them as "Sold Out" rather than hiding them.
  • The tenant object provides your brand colours for styling the widget to match your portal.
  • Occurrences with status cancelled are excluded automatically.

2. Get Single Session

Returns full details for one occurrence.

GET /sessions/{id}

  • {id} — the occurrence ID from a list response.

Example Response

{
  "data": {
    "id": 101,
    "title": "Summer Camp",
    "description": "Full description text...",
    "image_url": "https://...",
    "location": {
      "name": "Forest Park, Oak Lane",
      "map_url": "https://maps.google.com/?q=..."
    },
    "schedule": {
      "date": "2026-06-15",
      "start_time": "09:00:00",
      "end_time": "15:00:00"
    },
    "price": {
      "amount": 25.00,
      "currency": "GBP"
    },
    "capacity": {
      "total": 20,
      "remaining": 5,
      "status": "available"
    },
    "policies": {
      "cancellation_deadline_hours": 48
    }
  }
}

Pagination

Pagination uses an opaque cursor token:

  1. Check pagination.has_more in the response.
  2. If true, pass pagination.next_cursor as the cursor query parameter in your next request.
  3. Repeat until has_more is false.
GET /sessions?limit=20&cursor=MjAyNi0wNi0xNXwxMDE=

Rate Limiting

Limit Window
60 requests per 60 seconds, per IP

Exceeded requests return 429 Too Many Requests. Implement exponential backoff in your client.


Caching

Responses include standard HTTP cache headers:

  • Cache-Control: public, max-age=60 — responses are valid for 60 seconds.
  • ETag — compare against If-None-Match to receive 304 Not Modified and avoid re-parsing unchanged data.

Error Responses

All errors follow a consistent shape:

{ "error": "Description of the problem" }
Status Meaning
401 Missing or invalid API key
403 API not enabled for this tenant
404 Tenant or session not found
429 Rate limit exceeded
500 Internal server error

Best Practices

  • Never expose your API key in public JavaScript. If embedding client-side, consider proxying requests through your own backend.
  • Cache responses on your server for 60 seconds to reduce API calls and improve page load speed.
  • Respect is_full — display sold-out sessions with a disabled state rather than hiding them. This gives parents a better picture of your programme.
  • Use booking_url for all "Book Now" links — do not construct booking URLs manually.
Related Articles
Still stuck?

Our support team is happy to help.

Contact Us
Was this article helpful? Yes No