Skip to main content
Everything in this reference is generated from the OpenAPI document, which is derived from the published wire contract rather than written alongside it.

The surface

All three require Authorization: Bearer np_live_…. There is no unauthenticated route.

Base URL

{host} is the durable custom domain issued with your key. Pin the URL version explicitly, exactly as you pin an operating point: there is no implicit “latest” and nothing is served unversioned.

Two rules for your client

These are the client’s side of the contract. A client that ignores them will break on a change this API considers non-breaking.
1

Ignore response fields you do not recognise

New optional fields ship within /v1. Strict validation that rejects unknown fields breaks on the next additive change. The usage metering receipt is an example of one that has already shipped this way.
2

Do not exhaustively match the gate outcome or its reason

Branch on the top-level outcome (engaged, stood_down, escalated). gate is the envelope gate’s shadow assessment, not the decision: it runs at every published operating point without driving the result, and can legitimately disagree with outcome. See branch on outcome.The gate assessment is an open, extensible enum. gate.engaged is true for a select value and false for a stand down, with the trigger in gate.reason. New values and new reason prefixes ship additively within /v1, so tolerate ones you do not recognise.

Versioning policy

What counts as breaking, and the commitment that a version keeps serving until it is formally deprecated.

The simple shape: text instead of records

POST /v1/context/select also accepts a single string field, text, as an alternative to records[], for when you have raw pasted material rather than pre-split records. Needlepath splits it on blank lines into records of kind external_data, each with a content-hash id (sha256:<16 hex characters> of that record’s own text; you can recompute it yourself). task.prompt is required either way. budget.max_context_tokens is required on this path too: there is no default to fall back to. budget.operating_point stays optional, with the resolved label echoed in policy_version as always. Metering runs over the records Needlepath derived from your text, exactly as it would over records you sent yourself. text and records are mutually exclusive: sending both is a 400 with error: "text_and_records_both_set". See The simple shape in the quickstart for a worked example.

Fields with no effect

Some fields are part of the published contract, are accepted, and have no effect on the response. They are listed here rather than left for you to discover from a behaviour that does not change.
If a record must not be dropped, do not send it to be selected. With required_record_ids inert, the reliable way to guarantee a record reaches your prompt is to keep it out of records[] and concatenate it yourself around rendered_context. That is the correct pattern for a system prompt, a schema the model must call against, or the current user turn.
These are behaviour, not contract: each field stays in the schema, and a change in what it does is an additive change that needs no version bump on your side.

Reading the schemas

A few things are worth knowing before you read the field list:
  • usage is on every selection response. It is the metering receipt, and the one number that per-request output, telemetry and the wallet debit all share. See How billing works.
  • The 402 response is served. It carries error: "payment_required" and means the workspace is out of credit. Handle it distinctly from an auth failure: nothing about the credential is wrong. See Errors.
  • tokens_before / tokens_after are engine-internal accounting, not the billing quantity, and cannot be recomputed from your payload. See How to recompute your own bill.
  • A 200 is not always an engagement. A stand-down and an engine-internal failure both return 200 with a usable body. See Errors.
  • No method-tuning knobs appear in the request. Thresholds, weightings and gate parameters are resolved server-side from budget.operating_point. That is a contract property, not an omission.