Skip to content

Anthropic: Create message

Sends one prompt to the Claude Messages API and returns the reply.

  • Kind: anthropic.messages
  • Palette: Integrations, under Anthropic
  • Credential: a credential of kind api_key, named in credential
  • Classifying, summarising or drafting text inside a workflow, with the answer feeding a switch or a message.
  • Getting an answer in a fixed shape: give output_schema and branch on nodes.<id>.output.data, with no parsing step in between.
  • A single prompt and reply. For tools and multi-turn conversations, call the API from an http node and set the body yourself.
Field Required Description
model yes Claude model id, e.g. claude-sonnet-4-6 or claude-haiku-4-5. For example: claude-sonnet-4-6.
Field Type Required Description
prompt string yes The message to send. Reference upstream data with {{ … }}. Written in a markdown editor; the rendered HTML is stored beside it as <name>_html.
max_tokens integer no The most tokens the reply may use. A model that thinks spends from the same budget, and a reply cut off at it fails a step that gives output_schema, with no retry. From 1 to 131072. Default 1024.
output_schema object no A JSON Schema for the reply. When set, the model is asked to answer in this shape, and the parsed reply is the step’s data. The top must be an object, and every object needs “additionalProperties”: false.
output_name string no The name the schema goes by: the tool’s name in tool mode. Default "result".
output_mode string no How the shape is asked for: json_schema uses the API’s structured outputs; tool makes the model call one tool with the schema as its input, for older models and gateways without structured outputs. The newest Claude models refuse a forced tool call. One of "json_schema", "tool". Default "json_schema".

Beside with and input in the node’s config.

Field Type Required Description
credential string yes Name of the project credential the action authenticates with.
fail_on_error_status boolean no Treat any 4xx/5xx as a failure. On by default: an action either did its job or did not. Default true.
optional_when_untrusted boolean no Run without the credential when the run is untrusted (a fork pull request), instead of failing. The credential is still withheld.
retry_on array no Status codes that fail the node instead of returning, so its retry: policy applies (e.g. [429, 503]).

The HTTP response. The reply is under body: nodes.<id>.output.body.<field>.

Field Type Description
status integer The HTTP status code.
headers object The response headers.
body object The response body, parsed as JSON when it is JSON.
body.content array The reply, in blocks; content[0].text is the text of the first.
body.id string
body.model string
body.stop_reason string Why the reply ended: end_turn, max_tokens, …
body.usage object input_tokens and output_tokens.
data object The reply as JSON, checked against output_schema. Set only when the step gives one.
  • On an agent with the connector capability. The managed environments have one, so this needs no agent of your own.
  • One POST request to api.anthropic.com.
  • Any 4xx or 5xx fails the step, unless fail_on_error_status is false. retry: asks again after a 5xx, a 401, 408, 409, 423, 425 or 429, or a 4xx with Retry-After, and not after any other 4xx, which would get the same answer.
  • With output_schema set, the reply is parsed and checked against it and returned as data. A reply that does not fit fails the step, quoting what the model said; the step’s retry: sends the request again, except after a refusal or a cut-off reply.

Classify an email, then route on the category:

version: hyperspool-graph/v1
nodes:
- id: classify
type: anthropic.messages
config:
credential: claude
with: { model: claude-sonnet-4-6 }
input:
prompt: { $template: "Classify this support email. {{ input.email }}" }
output_schema:
type: object
properties:
category: { type: string, enum: [billing, bug, other] }
urgent: { type: boolean }
required: [category, urgent]
additionalProperties: false
retry: { attempts: 3, backoff: 2s }
- id: route
type: switch
config:
cases:
- { name: billing, when: "nodes.classify.output.data.category == 'billing'" }
- { name: bug, when: "nodes.classify.output.data.category == 'bug'" }
default: other
- id: page_billing
type: shell
config: { run: ./page-billing.sh }
- id: file_bug
type: shell
config: { run: ./file-bug.sh }
edges:
- { from: classify, to: route }
- { from: route, to: page_billing, when: billing }
- { from: route, to: file_bug, when: bug }

The parsed answer is nodes.classify.output.data, so nodes.classify.output.data.urgent is a boolean. The request uses the API’s structured outputs; for an older model or a gateway without them, set output_mode: tool and the model is made to answer through one tool call instead. The newest Claude models refuse a forced tool call, so keep the default for them. A reply that is not JSON or does not match the schema fails the step with the model’s text in the error, and retry: asks again; a refusal or a reply cut off at max_tokens is not asked again.

The API’s structured outputs refuse some of JSON Schema: numeric bounds (minimum, maximum, multipleOf, …), minLength and maxLength, maxItems, a minItems above 1, uniqueItems, and string formats outside its list. The request leaves those out and notes each one in its field’s description for the model to read. The reply is still checked for the bounds, so a number past its maximum fails the step like any other reply that does not fit; format and uniqueItems are not checked. In tool mode the schema goes out as written.

The API makes the model answer in the schema’s shape, so an enum gets one of its values even when none of them is right: asked for the capital of France with enum: [Oslo, Madrid, Tokyo], the model picks one of the three and the step succeeds. When the answer might not be on the list, add a value such as unknown or other and give it a branch.

Without output_schema the reply’s text is at nodes.<id>.output.body.content[0].text. The credential is an api_key sent as x-api-key: spool credential set claude --kind api-key --header x-api-key. Any 4xx or 5xx fails the step, so retry: alone covers a rate limit. A 400, such as a schema the API refuses, is not sent again. See Calling a model.

max_tokens caps the reply, 1024 unless the step sets it, up to 131072. A model that thinks before it answers spends from the same budget, so a thinking model given a long task may need more. A reply cut off at the cap ends with stop_reason: max_tokens; with output_schema set, that fails the step, and retry: does not ask again, since the same cap would cut it off again. Raise max_tokens instead. A large value can make the call take minutes, so check the step’s timeout:.

See Connectors for credentials and versions, and the node reference for every other node.