Skip to main content

Specifications

A Gnaww Specification is a durable immutable resource containing one completed canonical Gnaww Job Specification (GJS).

Use it when your application needs to obtain controlled demand from Gnaww, retain that exact demand, and refer to it later by a stable specification_id.

A Specification is not a Recipe. specification_id identifies a retained demand resource. Recipe ID identifies an exact physical manufacturing definition.

From intent to a durable Specification​

The normal flow is:

requirement
-> POST /v1/interpret
-> canonical_ready
-> response.gjs
-> POST /v1/specifications
-> specification_id
-> GET /v1/specifications/{specification_id}

POST /v1/interpret does not persist a Specification automatically. Retention is an explicit developer action.

1. Interpret the requirement​

curl https://api.gnaww.io/v1/interpret \
--request POST \
--header "X-Gnaww-API-Key: ${GNAWW_API_KEY}" \
--header "Content-Type: application/json" \
--data '{
"source": {
"type": "natural_language",
"raw_text": "500 A5 double-sided flyers on 170gsm silk"
},
"gjs_version": "0.4"
}'

Only continue to durable retention when the response contains completed canonical demand. If Gnaww returns clarification or review requirements, resolve those first.

2. Retain the completed GJS​

Take the returned gjs object without reinterpreting it in your application and send it to POST /v1/specifications.

curl https://api.gnaww.io/v1/specifications \
--request POST \
--header "X-Gnaww-API-Key: ${GNAWW_API_KEY}" \
--header "Content-Type: application/json" \
--data '{
"gjs": {
"schema_name": "jawwws.print_job_specification",
"schema_version": "0.4",
"status": "mapped",
"product_category": "commercial_print",
"product_family": "flyer",
"product_name": "A5 Flyer",
"quantity": {"units": 500, "variable_data": false},
"service_requirements": {
"maximum_turnaround_working_days": null,
"turnaround_basis": "unknown",
"requires_confirmed_availability": false
},
"components": [{
"component_id": "main",
"role": "main",
"size": {
"standard_name": "A5",
"width_mm": 148,
"height_mm": 210,
"orientation": "portrait"
},
"substrate": {
"category": "paper",
"finish": "silk",
"weight_gsm": 170,
"grammage_requirement": null,
"texture": null,
"material": null
},
"print_spec": {
"sides": "double_sided",
"colour": "full_colour",
"processes": []
},
"finishings": []
}],
"options": {
"folded_leaflet": null,
"apparel": null,
"fabric_homewares": null,
"promotional_goods": null,
"book_document": null
},
"use_requirements": [],
"confidence": 1,
"unresolved_fields": []
},
"idempotency_key": "my-job-4821-v1",
"external_references": [
{"system": "workflow", "reference": "job-4821"}
]
}'

Use a stable idempotency key when retrying the same retention request. Reusing the same key with different GJS or metadata returns 409 specification_idempotency_conflict.

3. Store the Specification ID​

A successful response contains a safe immutable resource:

{
"status": "created",
"specification": {
"schema_name": "gnaww.specification_resource",
"schema_version": "0.1",
"specification_id": "GNS-...",
"resource_version": 1,
"immutable": true,
"gjs_schema_name": "jawwws.print_job_specification",
"gjs_schema_version": "0.4",
"gjs": {},
"content_fingerprint_sha256": "...",
"external_references": [],
"field_provenance": [],
"recipe": {
"status": "eligible",
"recipe_id": "GNR-...",
"persisted": false,
"reasons": []
},
"created_at": "2026-08-31T00:00:00Z"
}
}

Store specification_id as the reference to this retained demand resource. Do not generate or infer it yourself.

4. Retrieve it later​

curl https://api.gnaww.io/v1/specifications/${SPECIFICATION_ID} \
--header "X-Gnaww-API-Key: ${GNAWW_API_KEY}"

Reads are tenant and workspace scoped. An unknown Specification and a Specification owned by another context both return 404 specification_not_found.

Recipe linkage​

A completed GJS can be a valid Specification even when it is not eligible for permanent Recipe identity. For example, controlled tolerant demand can remain valid while the exact physical manufacturing definition is not yet fixed.

When Recipe identity is eligible, the Specification exposes its deterministic Recipe ID. Creating the Specification does not persist a Recipe as a side effect. Use the Recipe API when you deliberately need the Recipe resource.

Two Specifications can have different Specification IDs and the same Recipe ID. That is expected when they are separate retained demand resources with the same physical manufacturing definition.

Scopes​

OperationRequired scope
POST /v1/specificationsspecifications:write
GET /v1/specifications/{specification_id}specifications:read

Specification scopes are deliberately separate from interpretation and Recipe scopes.

Not a production-order API​

A validated and retained Specification still does not confirm live price, stock, capacity, producer acceptance or an order. Specification retention preserves controlled demand. SpecMatch evaluates capability relationships. Live transaction and production behaviour remain separate concerns.