Result envelopes
Every command and query answers with a result envelope. The frontend packages parse these shapes, so they are the contract between the backend and the client. Arc for Elixir keeps them identical to the other Arc implementations; the Arc.EnvelopeTest specs pin each field name and type, so a change is always deliberate.
The Elixir structs are Arc.CommandResult and Arc.QueryResult. to_wire/1 on each produces the JSON body, and status/1 the HTTP status. Field names on the wire are camelCase.
Command result
Section titled “Command result”| Field | Type | Notes |
|---|---|---|
correlationId |
UUID string | Always present |
isAuthorized |
boolean | The authorization outcome |
validationResults |
array | Always present, empty when valid |
exceptionMessages |
array of string | Always present. Outside development the detail is replaced by a generic message |
exceptionStackTrace |
string | Empty when redacted or absent |
authorizationFailureReason |
string | Empty when authorized |
isValid |
boolean | true only when validationResults is empty, whatever the severity |
hasExceptions |
boolean | true when exceptionMessages is not empty |
isSuccess |
boolean | Authorized, valid and without exceptions |
response |
any | Present only on success and only when the command returned one |
isValid, hasExceptions and isSuccess are derived, never independent. A failed command never carries a response, so a client cannot receive a value alongside a failure it must not act on.
Query result
Section titled “Query result”| Field | Type | Notes |
|---|---|---|
correlationId |
UUID string | Always present |
data |
any | The query’s data; omitted when null, and absent on any failure |
isReady |
boolean | false for an observable query that has not produced a result |
isAuthorized |
boolean | The authorization outcome |
validationResults |
array | Always present |
exceptionMessages |
array of string | Always present |
exceptionStackTrace |
string | Empty when redacted or absent |
paging |
object | Always present: page (zero-based), size, totalItems, totalPages |
isValid, hasExceptions |
boolean | As for commands |
isSuccess |
boolean | Ready, authorized, valid and without exceptions |
totalPages is 0 when size is 0, otherwise totalItems divided by size, rounded up. A query that is not paged reports size: 0 and the number of items in totalItems. The delta changeSet of the contract is not produced; see Limits and gaps.
Validation result
Section titled “Validation result”| Field | Type | Notes |
|---|---|---|
severity |
number | 0 unknown, 1 information, 2 warning, 3 error |
message |
string | Developer-facing; free to change |
members |
array of string | The camelCase member names |
reason |
string | An open set; defaults to rule |
state |
any | Present only when set |
reasonDetail |
string | Present only when set |
See Validation for the reasons.
Status codes
Section titled “Status codes”The HTTP status is selected in a fixed order, which matters when a result carries more than one kind of failure.
| Order | Condition | Command | Query |
|---|---|---|---|
| 1 | Success | 200 | 200 |
| 2 | Not authorized | 403 | 403 |
| 3 | Validation failure | 400 | 400 |
| 4 | Not ready | 202 | |
| 5 | Exception | 500 | 500 |
An authentication handler that fails the request answers 401 before any envelope is built.
Identity
Section titled “Identity”GET /.cratis/me has its own shape: {id, name, isAuthenticated, isAuthorized, roles, details}, with empty 401 and 403 responses. See Authorization and identity.
Next steps
Section titled “Next steps”- Commands and Queries say how results are produced.
- The language-neutral Arc HTTP contract is the authority these shapes follow.