Environments
Playbooks show full URLs you can paste. Paths without a host are the same resource.
Dev (default in these docs)
| Layer | Base URL | Explorer |
|---|---|---|
| Core | https://backend-dev.bookdirect.live/public/api/v1/nellalink | Core docs |
| Middleware | https://middleware-dev.bookdirect.live/api/v1 | Middleware docs |
Core is served from Laravel public/, so the browser path includes /public. Middleware does not use /public.
Examples:
POST https://backend-dev.bookdirect.live/public/api/v1/nellalink/user/login
POST https://backend-dev.bookdirect.live/public/api/v1/nellalink/smart-meta-manager/entity/property
POST https://middleware-dev.bookdirect.live/api/v1/bookdirect/payments/initialize
POST https://middleware-dev.bookdirect.live/api/v1/nellalink/file-manager/aws/upload-urlHeaders every Core call needs
| Header | Required | Value |
|---|---|---|
x-api-key | Yes | Public browse key in the Vue app for listing active properties. Write key (JWT required) for creates/updates — do not put the write key in the browser if you can send writes through Middleware. See Security and IDOR. |
Authorization | Writes and private reads | Bearer {access_token} from login |
Content-Type | POST / PUT | application/json |
The browse key is assumed public. IDOR is Core path settings + Middleware, not frontend.
Headers every Middleware call needs
| Header | Required | Value |
|---|---|---|
Authorization | Yes (except PSP webhooks) | Same Core JWT (iss must be nellalink) |
x-api-key | When the route declares it | Same site key unless the Middleware folder uses its own |
Content-Type | POST / PUT | application/json |
Webhooks (Paystack, Squad, Tsara) use the provider signature header, not a user JWT.
Staging and live
Replace the host only. Paths stay the same.
| Env | Core host | Middleware host |
|---|---|---|
| Dev | https://backend-dev.bookdirect.live | https://middleware-dev.bookdirect.live |
| Staging | set when promoted | set when promoted |
| Live | set when promoted | set when promoted |
Document new hosts on /next first, then promote.
Standard response envelope (Core and Middleware)
json
{
"status": true,
"status_code": 200,
"message": "Login successful.",
"data": {},
"meta": { "pagination": {} }
}Errors:
json
{
"status": false,
"status_code": 422,
"message": "Validation error",
"error": {
"error_code": "optional-code",
"recommendation": ["What to fix"]
}
}JWT
- Issuer:
nellalink - Typical access-token life: 30 minutes. Use
POST .../user/refreshwith a refresh token, or re-login. - Store
data.uuid(user) anddata.access_token. Send that uuid asowned_byon creates. Core must reject a mismatch with the JWT.