Prefill and Purge API

These two endpoints let a service account warm or remove cached content on OpenCache without using the console UI. Both are asynchronous: a successful call records the request and returns immediately. The fleet then converges — each PoP writes its own status key, and the parent record's cacheStatus moves from pending → processing → completed (or failed).

The interactive equivalents are OpenCache → Pre-fill and OpenCache → Purge.

Signed in to PF Console? The Try it panels below run the same calls live against your session and selected project. They hit the console API (/opencache/prefill, /opencache/purge), which is the counterpart of https://baas.p.foundation/opencache/v1.1/.

Authentication

Every call needs a Directus Bearer token:

text
Authorization: Bearer <token>

A service account is fully supported. The token must belong to a user that:

  1. Holds the required policies directly — role-derived grants, including administrator, do not count.
  2. Is a member of the target project.

The public base URL used in this guide is https://baas.p.foundation/opencache/v1.1/.

Version

The public OpenCache API is versioned in the path.

VersionBase URLStatus
v1https://baas.p.foundation/opencache/v1/Stable
v1.1https://baas.p.foundation/opencache/v1.1/Rolling Release (beta)

This guide documents v1.1. Treat it as a preview — paths and fields may still change before it is marked stable. Use v1 for production integrations that need a frozen contract.

Required permissions

EndpointCreate (must hold)See the resource + track status
POST /prefillOpenCache/Pre-fill: WriteOpenCache/Resources: Read
POST /purgeOpenCache/Purge: WriteOpenCache/Resources: Read

Ask your P Foundation contact (or a console admin with Users: Write) to assign both policies directly to the service-account user and add that user to the project.

URL validation

Applies to every URL you submit on either endpoint.

  • Must be a valid absolute URL.
  • Must use https://.
  • Hostname must be either {resourceId}.ocs.p.foundation or one of the resource's configured domains.
  • Prefill accepts exact URLs only.
  • Purge additionally accepts a trailing /* wildcard (https://host/path/*) — that is the only permitted wildcard.

Prefill — POST /prefill

Warms the named URLs into cache on every PoP.

Request body

FieldTypeRequiredNotes
projectIdstring (UUID)yesProject that owns the edge resource
resourceIdstringyesKVS key, e.g. edgeResource:416863562947026945
urlsstring[]yesAt least one HTTPS URL on the resource
referencestringyesLabel shown in the console list
popsstring[]noDefaults to ["*"] (all PoPs)
scheduleMode"now" | "dynamic" | "later"noDefaults to "now"
scheduledAtISO-8601 string or nullnoRequired in practice when scheduleMode is "later"
parseStreamsbooleannoWhen true, the server expands HLS/DASH manifests into child prefill requests automatically — no second call

Example

curl --request POST \
  --url https://baas.p.foundation/opencache/v1.1/prefill \
  --header 'Authorization: Bearer $TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{"projectId":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee","resourceId":"edgeResource:416863562947026945","urls":["https://416863562947026945.ocs.p.foundation/index.m3u8"],"reference":"Prime-time bulletin","scheduleMode":"now"}'

Success (201)

json
{
  "code": 201,
  "serverErrorCode": null,
  "message": "Prefill request created",
  "data": { "prefillKey": "opencache:prefill:123456789012345678" }
}

The trailing snowflake on prefillKey is the id used in status URLs below.

Purge — POST /purge

Removes cached content from every PoP. Immediate only — there is no schedule.

purgeMode: "all" flushes every cached object for the resource. Use it only when that is what you mean.

Request body

FieldTypeRequiredNotes
projectIdstring (UUID)yesProject that owns the edge resource
resourceIdstringyesKVS key, e.g. edgeResource:416863562947026945
purgeMode"urls" | "all"noDefaults to "urls"
urlsstring[]when purgeMode is "urls"Exact HTTPS URLs and/or trailing /* patterns
referencestringyesLabel shown in the console list
popsstring[]noDefaults to ["*"] (all PoPs)

Example — exact URL + wildcard

curl --request POST \
  --url https://baas.p.foundation/opencache/v1.1/purge \
  --header 'Authorization: Bearer $TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{"projectId":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee","resourceId":"edgeResource:416863562947026945","purgeMode":"urls","urls":["https://cdn.example.com/index.html","https://cdn.example.com/assets/*"],"reference":"Drop stale assets"}'

Example — entire resource

curl --request POST \
  --url https://baas.p.foundation/opencache/v1.1/purge \
  --header 'Authorization: Bearer $TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{"projectId":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee","resourceId":"edgeResource:416863562947026945","purgeMode":"all","reference":"Full flush after origin cutover"}'

Success (201)

json
{
  "code": 201,
  "serverErrorCode": null,
  "message": "Purge request created",
  "data": { "purgeKey": "opencache:purge:123456789012345678" }
}

Errors

Same envelope on both endpoints.

HTTPserverErrorCodeWhen
400VALIDATION_FAILEDMissing field, URL not HTTPS, hostname not on the resource, empty urls (unless purgeMode is "all")
401UNAUTHORIZEDMissing or invalid Bearer token
403FORBIDDENToken is valid but the user does not hold the Write policy directly
500INTERNAL_SERVER_ERRORPersistence or lookup failed
json
{
  "code": 403,
  "serverErrorCode": "FORBIDDEN",
  "message": "OpenCache/Purge: Write policy required",
  "data": null
}

A 400 for a resource the caller cannot see looks like this (the server does not distinguish "does not exist" from "hidden by policy"):

json
{
  "code": 400,
  "serverErrorCode": "VALIDATION_FAILED",
  "message": "Resource not found or not accessible",
  "data": null,
  "errors": [
    { "field": "resourceId", "message": "Could not find the specified edge resource in your project" }
  ]
}

Tracking progress

Readable with OpenCache/Resources: Read. A 404 means the request is missing or not visible to this token.

List

Prefill:

curl --request GET \
  --url 'https://baas.p.foundation/opencache/v1.1/prefill?projectId=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' \
  --header 'Authorization: Bearer $TOKEN'

Purge:

curl --request GET \
  --url 'https://baas.p.foundation/opencache/v1.1/purge?projectId=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' \
  --header 'Authorization: Bearer $TOKEN'

Optional limit (default 1000). Newest first (dateCreated descending).

Detail

Prefill:

curl --request GET \
  --url 'https://baas.p.foundation/opencache/v1.1/prefill/123456789012345678?projectId=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' \
  --header 'Authorization: Bearer $TOKEN'

Purge

curl --request GET \
  --url 'https://baas.p.foundation/opencache/v1.1/purge/123456789012345678?projectId=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' \
  --header 'Authorization: Bearer $TOKEN'

{id} is the trailing snowflake from prefillKey / purgeKey.

json
{
  "code": 200,
  "serverErrorCode": null,
  "message": "Purge request",
  "data": {
    "record": {
      "key": "opencache:purge:123456789012345678",
      "dateCreated": "2026-08-18T12:00:00.000Z",
      "dateUpdated": "2026-08-18T12:00:08.000Z",
      "value": {
        "cacheStatus": "processing",
        "purgeMode": "urls",
        "urls": ["https://cdn.example.com/index.html"],
        "pops": ["*"],
        "reference": "Drop stale assets",
        "resourceId": "edgeResource:416863562947026945",
        "resourceName": "Example"
      }
    },
    "pops": [
      {
        "popId": "bey-01",
        "city": "Beirut",
        "country": "Lebanon",
        "countryIso": "LB",
        "continent": "AS",
        "status": "completed"
      }
    ]
  }
}

record.value.cacheStatus is the fleet-level roll-up. pops[] is the resolved per-PoP view (* expanded to enabled first-party PoPs). Prefill detail also includes parent and children when the request was produced by (or produced) manifest expansion.

StatusMeaning
pendingAccepted; edges have not started
processingAt least one PoP is working
completedFleet finished successfully
failedAt least one PoP failed
scheduledPrefill only — waiting for scheduledAt / off-peak