Home / Docs / API reference

/v1/responses

POST /v1/responses

Authentication relay key (bearer)

Request body

FieldTypeDescription
modelstringThe model id. In a request it is optional: without it the key's routing chooses.
input requiredstring or arrayRequired: a string or a list of {role?, content} items (role defaults to user).
instructionsstringBecomes a leading system message; blank text contributes nothing.
max_output_tokensnumber
temperaturenumberSampling temperature: lower is more deterministic, higher more varied. Usually between 0 and 2.
streamboolean
reasoningobjectOnly reasoning.effort is read.
reasoning.effortstring

Example request

curl
curl -X POST https://api.massrelay.ai/v1/responses \
  -H "Authorization: Bearer $RELAY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input":"Say hello in one sentence."}'
Python
import os, requests

r = requests.post(
    "https://api.massrelay.ai/v1/responses",
    headers={"Authorization": f"Bearer {os.environ['RELAY_KEY']}"},
    json={
        "input": "Say hello in one sentence."
    },
)
r.raise_for_status()
print(r.json())
TypeScript
const r = await fetch("https://api.massrelay.ai/v1/responses", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.RELAY_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({"input":"Say hello in one sentence."}),
});
if (!r.ok) throw new Error(`${r.status} ${await r.text()}`);
console.log(await r.json());

Response

FieldTypeDescription
id requiredstringresp_<decisionId>
object requiredstringThe kind of object returned, for example chat.completion. Always "response".
created_atinteger
modelstringThe model id. In a request it is optional: without it the key's routing chooses.
status requiredstring Always "completed".
output requiredarray of object
output[].typestring Always "message".
output[].idstringThe answer's id.
output[].statusstring
output[].rolestringWho wrote the message: system, user, assistant or tool. Always "assistant".
output[].contentarray of objectThe text of the message.
output[].content[].typestring Always "output_text".
output[].content[].textstring
output[].content[].annotationsarray
output_text requiredstring
usage requiredobjectTokens counted for this call.
usage.input_tokensnumberTokens in the input.
usage.output_tokensnumberTokens generated.
usage.total_tokensnumberInput plus generated tokens.
Example response (shape)
{
  "id": "resp_1f2e3d4c",
  "object": "response",
  "created_at": 1761400000,
  "model": "provider/model-id",
  "status": "completed",
  "output": [
    {
      "type": "message",
      "role": "assistant",
      "content": [
        {
          "type": "output_text",
          "text": "Hello there."
        }
      ]
    }
  ],
  "output_text": "Hello there.",
  "usage": {
    "input_tokens": 12,
    "output_tokens": 6,
    "total_tokens": 18
  }
}

Common errors

  • 401 invalid_api_key
  • 400 the body is not usable
  • 402 out of credit or over a budget
  • 413 the body is over the limit
  • 403 insufficient_scope
  • 429 over the request rate; read Retry-After

Every error has the same JSON shape; see Errors and Limits.

Full schema (JSON)

Request schema

{
  "description": "Every other field is accepted and not read (tools and previous_response_id are not read on this surface). Fields the gateway does not read are not documented as honoured.",
  "type": "object",
  "required": [
    "input"
  ],
  "additionalProperties": true,
  "properties": {
    "model": {
      "type": "string"
    },
    "input": {
      "description": "Required: a string or a list of {role?, content} items (role defaults to user).",
      "type": [
        "string",
        "array"
      ]
    },
    "instructions": {
      "type": "string",
      "description": "Becomes a leading system message; blank text contributes nothing."
    },
    "max_output_tokens": {
      "type": "number"
    },
    "temperature": {
      "type": "number"
    },
    "stream": {
      "type": "boolean"
    },
    "reasoning": {
      "type": "object",
      "properties": {
        "effort": {
          "type": "string"
        }
      },
      "additionalProperties": true,
      "description": "Only reasoning.effort is read."
    }
  }
}

Response schema

{
  "description": "Every other field is accepted and not read (streaming is not described here). Fields the gateway does not read are not documented as honoured.",
  "type": "object",
  "additionalProperties": true,
  "required": [
    "id",
    "object",
    "status",
    "output",
    "output_text",
    "usage"
  ],
  "properties": {
    "id": {
      "type": "string",
      "description": "resp_<decisionId>"
    },
    "object": {
      "const": "response"
    },
    "created_at": {
      "type": "integer"
    },
    "model": {
      "type": "string"
    },
    "status": {
      "const": "completed"
    },
    "output": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "type": {
            "const": "message"
          },
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "role": {
            "const": "assistant"
          },
          "content": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "const": "output_text"
                },
                "text": {
                  "type": "string"
                },
                "annotations": {
                  "type": "array"
                }
              }
            }
          }
        }
      }
    },
    "output_text": {
      "type": "string"
    },
    "usage": {
      "type": "object",
      "properties": {
        "input_tokens": {
          "type": "number"
        },
        "output_tokens": {
          "type": "number"
        },
        "total_tokens": {
          "type": "number"
        }
      }
    }
  }
}

Every answer carries a decision id; the explain endpoint returns why that model was chosen.