Responses
Every endpoint returns either a fixed body (static) or one chosen by the request (matched). Database-backed responses live under Data models and Endpoints.
Static
Return fixed JSON for endpoints that don't need a database: health checks, config, version info, anything static.
The inline key
Put your literal JSON under an inline: key. Akuma returns it verbatim with the endpoint's status code. No database, no schema.
- path: /status
method: GET
response:
inline:
status: ok
version: "1.0.0"
status: 200 curl http://localhost:3000/status
# => {"status": "ok", "version": "1.0.0"} Any JSON shape
The value under inline: can be an object, an array, or a scalar. Whatever you put is what you get back.
- path: /config
method: GET
response:
inline:
environment: development
features:
- authentication
- analytics
maintenance: false
status: 200 Explicit by design
Every response declares itself as either static (inline:) or database-backed (schema:). It is never inferred. A literal body is never mistaken for a schema, and vice versa. A bare mapping without one of these keys is rejected with a clear error.
Common mistakes
A static body must live under inline:. Writing it bare (the old style) fails to parse:
Error: Failed to parse config: ... unknown field `status`, expected one of `type`, `schema`, `inline` And a response is one or the other, never both:
Error: Failed to parse config: ... a response must have either `schema:` or `inline:`, not both Matched
When the response depends on the request, return different bodies from one endpoint: auth success vs failure, selection by query or header, error cases. No scripting.
The responses key
Replace a single response: with responses: - an ordered list of branches. The first branch whose when: matches the request wins. Each branch has an inline: body and an optional status:; an else: true branch is the fallback.
- path: /config
method: GET
responses:
- when: { query: { brand: nordcare } } # ?brand=nordcare
inline: { brandSlug: nordcare }
- when: { header: { authorization: { absent: true } } }
status: 401
inline: { error: "Missing token" }
- else: true # nothing above matched
status: 404
inline: { error: "No instance" } curl "http://localhost:3000/config?brand=nordcare"
# => {"brandSlug": "nordcare"}
curl http://localhost:3000/config
# => 401 {"error": "Missing token"} Sources
A when: groups conditions by where they read from. All conditions in a when: must hold (logical AND).
query- URL query parameters (?brand=nordcare)body- top-level fields of the JSON request bodyheader- request headers, matched case-insensitivelypath- named path parameters (:subject)
Conditions
Each condition is either a scalar (equality shorthand) or a one-key map:
brand: nordcareor{ eq: nordcare }- equals{ in: [a, b] }- one of these values{ present: true }- the value is present{ absent: true }- the value is not present
- path: /oauth/authorize
method: POST
responses:
- when: { body: { password: { absent: true } } }
status: 400
inline: { error: "Enter your password" }
- when: { body: { username: { in: [a@x.example, b@x.example] } } }
inline: { code: ok_1 }
- else: true
status: 401
inline: { error: "No account for that email" } Lookups by path parameter
Match a named :param to return per-id bodies without a database:
- path: /members/:subject
method: GET
responses:
- when: { path: { subject: nc_sub_4a91f0 } }
inline: { status: ACTIVE, plan: premium }
- else: true
status: 404
inline: { error: "Member not found" } Rules
An endpoint uses either response: or responses:, never both. If no branch matches and there is no else:, the request gets a 404. Branches are static (inline:) bodies; database-backed CRUD stays on the single response: form (see Endpoints and Mutations).