Developers
The API is the product
Directwerk is API-first: multi-tenant whitelabel, host-based tenant resolution, OAuth2, and modular feature gates with machine-readable error codes. This page is an excerpt — install guide, OpenAPI reference, and integration guides live in the public documentation.
How integrators connect
- Tenant via verified Host header (no X-Tenant-Id).
- Public content under GET /api/v1/public/* without authentication.
- Protected flows with OAuth2 JWT via POST /oauth2/token.
Key endpoints
A selection of the most relevant paths — not the full reference.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/public/site-config Branding and active modules — starting point for every frontend. | Branding and active modules — starting point for every frontend. |
| GET | /api/v1/public/episodes Public catalog (FREE playable; PAID metadata only, audioCdnUrl = null). | Public catalog (FREE playable; PAID metadata only, audioCdnUrl = null). |
| GET | /api/v1/public/products Membership products and prices for the pricing page. | Membership products and prices for the pricing page. |
| GET | /feeds/{tenantSlug}/podcast.xml Public RSS feed for podcatchers (tenant-scoped like the API). | Public RSS feed for podcatchers (tenant-scoped like the API). |
| GET | /feeds/{tenantSlug}/u/{feedToken}.xml Private subscriber feed (tokenized URL). | Private subscriber feed (tokenized URL). |
| POST | /oauth2/token OAuth2 token for publisher and subscriber JWTs. | OAuth2 token for publisher and subscriber JWTs. |
| GET | /api/v1/me/episodes Entitled episodes for signed-in subscribers. | Entitled episodes for signed-in subscribers. |
| POST | /api/v1/me/billing/checkout-sessions Stripe Checkout — billing entirely via the API. | Stripe Checkout — billing entirely via the API. |
Example: site-config
Every public frontend integration starts with branding and active modules.
curl -sS \
-H "Host: podcast.beispiel.de" \
https://api.directwerk.org/api/v1/public/site-configResponse format
Unified JSON envelope; errors include structured codefields for integrators.
Success
{
"statusCode": 200,
"statusMessage": "OK",
"data": { "tenant": { "slug": "beispiel" }, "enabledModules": ["PODCAST"] },
"errors": [],
"metadata": {}
}Module disabled
{
"statusCode": 403,
"statusMessage": "Forbidden",
"data": null,
"errors": [{ "code": "FEATURE_NOT_ENABLED", "message": "Module PODCAST_RSS is not active" }],
"metadata": {}
}