Skip to Content

Pod API

Solidus Pod is the personal-data-sovereignty layer: each user gets a real Solid pod they control, backed by Community Solid Server (CSS) 7.1.9. This is a genuinely spec-conformant Solid server — Linked Data Platform (LDP), Web Access Control (WAC), Solid-OIDC, and WebID are all served by CSS itself, not reimplemented by Solidus.

Solidus’s own code is a thin layer in front of it: a provisioning API that turns a freshly authenticated did:solidus user into a real pod, seeded with a WebID card that bridges the pod to their DID.

There are two distinct surfaces here — don’t conflate them:

SurfaceWhat it isWho wrote it
pod.solidus.network/<slug>/*The Solid pod itself — LDP resources, WAC, WebID, Solid-OIDCCommunity Solid Server (third-party, upstream)
pod.solidus.network/v1/*Provisioning — create a pod for a did:solidus userSolidus (pod/apps/backend)

Authentication

Two different auth mechanisms, one for each surface:

  • The pod itself (/<slug>/*) uses standard Solid-OIDC — CSS issues and verifies its own access tokens against its own account system. Read/write access is governed by WAC ACL resources, not by anything Solidus-specific.
  • The provisioning API (/v1/provision) is authenticated by the caller’s Solid-OIDC access token issued by auth.solidus.network (Authorization: Bearer <token> or DPoP <token>, ES256 JWT, aud: "solid"), verified against auth’s own JWKS. The pod slug is derived from the token’s WebID — a caller can only ever provision their own pod, never someone else’s.

Route index

Route groupPathAuth
Pod resources (LDP/WAC)/<slug>/* — e.g. /<slug>/profile/card, /<slug>/.aclSolid-OIDC + WAC (per-resource)
Well-known/.well-known/solid, /<slug>/.well-known/...Public (metadata)
Provisioning statusGET /v1/provisionSolid-OIDC bearer
Provisioning createPOST /v1/provisionSolid-OIDC bearer
HealthGET /v1/healthNone

pod-api is provisioning-only. Earlier route files for auth/files/credentials/shared/apps exist in the backend source tree but are retired and not registered — the pod UI now reads and writes the Solid pod directly via @inrupt/solid-client and logs in via Solid-OIDC, so that REST layer was never wired into the running app. Don’t build against them.


The Solid surface

This part of the product is the standards, so the best reference is the Solid protocol specification and CSS’s own documentation — not a Solidus-authored route table. A few things confirmed live against pod.solidus.network:

curl -s -D - https://pod.solidus.network/.well-known/solid
HTTP/2 501 x-powered-by: Community Solid Server link: <https://pod.solidus.network/.well-known/solid.meta>; rel="describedby" link: <https://pod.solidus.network/.notifications/StreamingHTTPChannel2023/b0>; rel="http://www.w3.org/ns/solid/terms#updatesViaStreamingHttp2023" link: <https://pod.solidus.network/.well-known/solid.acl>; rel="acl" {"name":"NotImplementedHttpError","message":"Only supports descriptions of storage containers.","statusCode":501,"errorCode":"H501"}

The 501 body is CSS’s own honest response — .well-known/solid discovery is scoped to storage containers in this CSS version, not the server root. The headers are the interesting part: real rel="acl" and rel="describedby" Link headers, and a real StreamingHTTPChannel2023 notification-channel Link — this is a live, spec-conformant Solid server, not a mock.

curl -s -D - -H "Accept: text/turtle" https://pod.solidus.network/<slug>/profile/card
HTTP/2 401 x-powered-by: Community Solid Server www-authenticate: Bearer scope="openid webid" link: <https://pod.solidus.network/<slug>/profile/card.meta>; rel="describedby" link: <https://pod.solidus.network/<slug>/profile/card.acl>; rel="acl"

On this deployment, the WebID profile card itself requires an authenticated read (401 without a token, with a WWW-Authenticate: Bearer scope="openid webid" challenge) — this is a per-pod WAC policy, not a Solidus API contract, and can differ pod to pod.


Provisioning API

Status

curl https://pod.solidus.network/v1/provision \ -H "Authorization: Bearer <solid-oidc access token>"
// Response 200 { "provisioned": true, "webId": "https://pod.solidus.network/ada/profile/card#me", "did": "did:solidus:testnet:...", "podUrl": "https://pod.solidus.network/ada/", "slug": "ada" }
// Response 401 — missing/invalid token { "error": "unauthorized", "message": "missing Authorization header" }
// Response 400 — token's WebID isn't under this pod's base URL { "error": "bad_webid", "message": "WebID is not under the pod base" }

Note this endpoint does not use the RFC 7807 Problem Details format the other Solidus backends use — errors here are a flat { error, message } object.

Create

Idempotent — calling it again on an already-provisioned pod returns alreadyProvisioned: true rather than erroring.

curl -X POST https://pod.solidus.network/v1/provision \ -H "Authorization: Bearer <solid-oidc access token>" \ -H "content-type: application/json" \ -d '{"displayName": "Ada"}'
// Response 200 — first provision { "ok": true, "alreadyProvisioned": false, "slug": "ada", "did": "did:solidus:testnet:...", "podUrl": "https://pod.solidus.network/ada/", "webId": "https://pod.solidus.network/ada/profile/card#me", "containers": [ "https://pod.solidus.network/ada/credentials/", "https://pod.solidus.network/ada/data/" ] }
// Response 200 — already provisioned { "ok": true, "alreadyProvisioned": true, "webId": "https://pod.solidus.network/ada/profile/card#me", "did": "did:solidus:testnet:...", "podUrl": "https://pod.solidus.network/ada/", "slug": "ada" }

Provisioning creates a CSS account, a login method the user never actually uses (the user authenticates via auth.solidus.network Solid-OIDC, never CSS’s own password login), the pod itself, and overwrites the seeded WebID card with a did:solidus-bridged profile document — this is what lets a did:solidus DID and a Solid WebID resolve to the same identity.

displayName is optional, trimmed, and capped at 100 characters.

Health

curl https://pod.solidus.network/v1/health
// Response 200 — measured live { "status": "ok", "service": "pod-backend", "timestamp": "2026-07-29T11:24:58.599Z" }

What this is not

  • Not a Solidus-authored storage API. File upload/download, resource listing, and permission management happen through the standard Solid protocol (LDP GET/PUT/POST/PATCH/DELETE, WAC .acl resources) against CSS directly — there is no pod.solidus.network/v1/files or similar Solidus route. Use a Solid client library (e.g. @inrupt/solid-client) against the pod URL.
  • Not a custom permission engine. Access control is WAC, served by CSS, not a Solidus-specific authorization layer.
Last updated on