Specira sample artefact. Rendered from the governed default template on a fictional company. Names, figures and dates are illustrative.All artefacts →
SAMPLE
seeded demo data · specira.ai
Specira API Contracts: Governed Template Rendering
Governed template rendering reference: API Contracts default v2 (draft) definition 83d8fd7f…259f
API Contracts · Project artifact SPECIRA

API Contracts: Dispatch Modernization

Meridian Field Services: instructional example, not project evidence

Draft · watermark policy: draft_only template api_contracts v2 · pack: specira_default_delivery spec-first · the OpenAPI file owns schema; this artifact owns the promise
§1

API Overview & Conventions

mandatory 1 decision1 evidence rule validators: style_versioning_pagination_each_one_logged_decision · conventions_stated_once_and_referenced · no_uri_path_versioning

The style is a decision, the conventions are stated once, and the spec is the source of truth; everything below references this section instead of re-deciding.

Style decision: REST

What: resource-oriented HTTP, a graph query layer, binary RPC. Why considered: consumers are the board (browser), the technician mobile app, and one inbound vendor webhook; no cross-resource aggregation need exists (the board's read model is server-composed) and vendor tooling expects plain HTTP. Who & how: E. Sandoval with A. Reyes, walked against the four screens and the integration register, July 16. Findings: GraphQL rejected (no aggregation consumer; cache and authorization complexity unjustified); gRPC rejected (browser and vendor compatibility cost) (API-style decision[1]).

Spec-first: the OpenAPI file lives at api/openapi.yaml, pinned per release; reference docs and client types generate from it; this artifact carries the invariants, the registry, and the matrix.

Convention (stated once)Rule
Namingsnake_case fields · plural collections (/jobs, /assignments) · nesting ceiling 2
Paginationpage_size (max 200) + page_token → next_page_token
Filtering / orderingfilter= · order_by= per the list convention
Versioningv1; breaking = rename or removal, new required field, changed status or error semantics; 180-day deprecation window with Deprecation + Sunset headers; no URI versioning (versioning decision[1])

Resources: jobs, technicians, assignments, positions, suggestions (five roots, under the ceiling of eight); each maps to its data-model entity (entities[2]).

§2

Endpoint Specifications

mandatory 1 decision1 evidence rule validators: every_endpoint_has_worked_example · every_endpoint_has_error_catalog_reference · rate_limits_and_slos_are_numbers · slo_classes_cite_architecture_quality_scenarios

Every row carries its example, its errors, its auth citation, and its SLO class. Limits are numbers because they protect the SLO, and say so.

Classp95 budgetSource
read300 ms quality scenarios[3] (cited, not invented)
write500 ms
computed800 ms (inside the sub-second suggestion budget)

Rate limits: staff sessions 600 req/min (burst 900); vendor webhook ingress 900/min (burst 1500, from the feed contract); mobile 120/min.

EndpointPurposeAuth (cites policy)ErrorsClassExample
GET /jobs List jobs; filters status, hub; pagination convention §1 dispatcher, ops manager[4] validation_failed · rate_limited readEX-1
POST /assignments Create assignment; Idempotency-Key required: 24-h retention; reuse with different parameters returns conflict_key_reuse (US-1[5]) dispatcher · hub scope[4] authority_denied · stale_version writeEX-3
POST /overrides Record override; reason_code required (FR-013[6]) dispatcher[4] validation_failed · authority_denied writeEX-4
GET /jobs/{id}/suggestions Ranked candidates; degradation contract §4 dispatcher[4] suggestions_unavailable computedEX-5
GET /positions Vehicle positions; band-masked off dispatch surfaces per the handling matrix (labels[7]) dispatcher, fleet manager[4] rate_limited readEX-6
POST /webhooks/positions Vendor feed ingress: contract in §5 machine · vendor signature[4] signature_invalid · rate_limited writeEX-7

Every example is a tested request/response pair in the example set (example set[8]); payload fields cite data-model ids, never re-describe them.

§3

Authentication & Authorization

mandatory 1 decision1 evidence rule validators: every_endpoint_cites_auth_role_not_inline_defined · matrix_cells_resolve_to_policy_roles_or_machine_identities

The policy owns the roles; this artifact owns which endpoint group needs which. Nothing is redefined here.

Endpoint groupPolicy role (cited)Note
jobs read dispatcher · ops manager[4] ops manager read-only; fleet manager denied
assignments create dispatcher[4] within hub scope, server-enforced
overrides create dispatcher[4] reason required
positions read dispatcher · fleet manager[4] masking per classification
feed configuration fleet manager[4] none
role administration platform admin[4] no wildcard; the policy's matrix law

Enforcement: server-side denial, not hidden buttons (SR-004[9]). Machine access: the positions webhook authenticates by vendor signature with quarterly rotation (machine identity[4], SR-021[9]); the notification worker and adapter use platform service accounts with short-lived tokens.

§4

Error Registry

mandatory 1 decision1 evidence rule validators: every_error_type_exists_in_closed_registry · registry_rows_state_when_raised_and_driver · degradation_contracts_present_where_architecture_commits_fallback

One envelope: RFC 9457 problem details. One closed registry: a new type is a review with the API owner, never an author's invention. Type URIs under api.meridianfield.example/errors/.

TypeStatusWhen raisedDriver
validation_failed422 Malformed or out-of-contract input SR-006[9]
authority_denied403 Role or scope check failed server-side SR-004[9] · TM-03[10]
not_found404 Resource id does not resolve within the caller's scopenone
stale_version409 Optimistic-lock version mismatch concurrency[2]
conflict_key_reuse409 Idempotency-Key reused with different parameters§2 rule
rate_limited429 The tier's numeric limit; Retry-After carried§2 limits
signature_invalid401 Webhook signature or replay-window failure SR-021[9]
suggestions_unavailable503 Degradation contract: the ranked-suggestion path degraded; the board proceeds with the full list degradation posture[3]

The degradation row exists because the architecture commits the fallback; clients build against it instead of discovering it in production.

§5

Webhooks & Eventing

conditional · inbound feed exists, ENGAGED 1 decision1 evidence rule validators: every_webhook_documents_signature_and_retry_semantics · webhook_ordering_rule_stated

Verify before you parse; reconcile on state, never on arrival order.

RuleVendor positions webhook (inbound)
Signature HMAC-SHA256 over the raw body + timestamp header; replay window 300 s; verified before parsing or any side effect (SR-021[9], TM-01[10])
Delivery At-least-once; vendor exponential backoff over 6 h; receiver deduplicates on the vendor event id
Ordering Arrival order untrusted: the adapter reconciles on observed_at, never arrival sequence (INT-1[3])
Receiver responses 2xx accepted · 401 signature_invalid = poison (no retry) · 429 / 5xx = retry

Outbound: none at pilot; assignment notifications flow through the notification gateway (INT-2[3]), not webhooks; stated so the absence is a claim.

§6

Open Questions

mandatory1 decision
QuestionOwnerAnswer byBlocks
Does the vendor's certificate-rotation drill need a partner sandbox before the quarterly rotation (machine identity[4])? E. SandovalSep 5, 2026 The rotation runbook only, not the contract
Refs

References & Package Contents

In this export package

package [8] Example set: tested request/response pairs EX-1…EX-7 ./api/examples/

In the Specira workspace

specira [1] Decision log: API-style and versioning decisions app.specira.ai/projects/dispatch-modernization/artifacts/decision-log
specira [2] Data model: entities, concurrency rule app.specira.ai/projects/dispatch-modernization/artifacts/data-model
specira [3] Architecture: quality scenarios, INT-1/INT-2, degradation posture app.specira.ai/projects/dispatch-modernization/artifacts/architecture
specira [4] Auth & authz policy: permission matrix, machine identity app.specira.ai/projects/dispatch-modernization/artifacts/auth-authz-policy
specira [5] User stories: US-1 app.specira.ai/projects/dispatch-modernization/artifacts/user-stories#us-1
specira [6] FRD: FR-013 override reason app.specira.ai/projects/dispatch-modernization/artifacts/frd#fr-013
specira [7] Data classification: handling matrix (position masking) app.specira.ai/projects/dispatch-modernization/artifacts/data-classification#labels
specira [9] Security requirements: SR-004, SR-006, SR-021 app.specira.ai/projects/dispatch-modernization/artifacts/security-requirements
specira [10] Threat model: TM-01, TM-03 app.specira.ai/projects/dispatch-modernization/artifacts/threat-model
Generated by Specira · template api_contracts v2 (draft) · pack specira_default_delivery lineage 83d8fd7f…259f · page 1 of 6