Skip to main content

List Tenants

Retrieve a cursor-paginated directory of every tenant on the platform that has an active plan.

This is a cross-tenant route (no {tenant} parameter), so it requires the cross-tenant ability in addition to tenants:read.


Endpoint

GET /internal-api/v1/tenants

Required abilities

tenants:read AND cross-tenant


Query Parameters

ParameterTypeDefaultDescription
per_pageinteger100Items per page. Integer between 1 and 500.
cursorstring-Cursor token from links.next or links.prev

per_page is validated server-side. Values outside 1..500, non-integers, decimals, and negatives all return 422 with the standard Laravel validator envelope. Omit the parameter to use the default of 100.


Response

Success (200 OK)

{
"data": [
{
"id": "1",
"name": "Publica",
"subdomain": "exquisite-hurricane-fc4hpnbsvaqj.vapor-farm-b1.com",
"final_domain": "app.publica.la",
"https": true,
"lang": "en"
},
{
"id": "2",
"name": "Barcelona Digital",
"subdomain": "barcelona-wfsrt-59-ytqs.farfalla-saas-caname.publicala.com",
"final_domain": "revisbarcelona.publicala.me",
"https": true,
"lang": "es"
},
{
"id": "14",
"name": "Ciudad Nueva",
"subdomain": "ciudadnueva-qetffdw-93.app.publica.la",
"final_domain": "ciudadnueva.publicala.me",
"https": true,
"lang": "es"
}
],
"links": {
"next": "https://app.publica.la/internal-api/v1/tenants?per_page=3&cursor=eyJpZCI6MTQsIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0",
"prev": null
},
"meta": {
"has_more": true
}
}

Ids are serialized as strings. The listing includes every tenant with an active plan on the platform, including publica.la itself as a read-only entry. Tenants without an active plan are not returned. Mutating endpoints target customer tenants only.


Examples

Basic list

curl -X GET "https://app.publica.la/internal-api/v1/tenants" \
-H "Authorization: Bearer <id>|pla_int_<secret>" \
-H "Accept: application/json"

Paginate

# Page 1
curl -X GET "https://app.publica.la/internal-api/v1/tenants?per_page=50" \
-H "Authorization: Bearer <id>|pla_int_<secret>" \
-H "Accept: application/json"

# Response includes:
# "links": { "next": "...?per_page=50&cursor=eyJpZCI6NTAs..." }

# Page 2
curl -X GET "https://app.publica.la/internal-api/v1/tenants?per_page=50&cursor=eyJpZCI6NTAs..." \
-H "Authorization: Bearer <id>|pla_int_<secret>" \
-H "Accept: application/json"

Iterate until meta.has_more is false. Treat the cursor as opaque and do not parse or modify it. Its format is an implementation detail and may change without notice.


Error Handling

422 Invalid per_page

{
"message": "The per page field must be an integer.",
"errors": {
"per_page": ["The per page field must be an integer."]
}
}

per_page failed validation (out of 1..500, non-integer, decimal, or negative).

401 Unauthenticated

{
"message": "Unauthenticated."
}

Causes: missing Bearer, only X-User-Token sent, or revoked token.

403 Missing ability

{
"message": "Invalid ability provided."
}

The token is missing tenants:read, cross-tenant, or both.

404 Wrong host

{
"message": "Not found"
}

The request resolved to a non-platform host. The Internal API only serves the platform host (app.publica.la). Setting X-Farfalla-Tenant-Id to a non-platform tenant id also returns 404, because it points the resolved tenant away from the platform.

429 Rate limited

HTTP/1.1 429 Too Many Requests
Retry-After: <seconds>

{
"message": "Too Many Attempts."
}

The token has spent its 60 RPM budget for the current minute.


See also

X

Graph View