Claude · Anthropic

Use Claude API through Tikway: the Anthropic Messages protocol

Last updated:

Start with a minimal Claude text request, then add system instructions and conversation history. This guide uses curl, saves responses, extracts text blocks and checks truncation and tool requests for an Anthropic Messages integration.

The full endpoint is https://api.tikway.ai/v1/messages, authenticated with a Tikway key in x-api-key. Requests are billed by usage. Check the catalog for protocol support, parameters and current prices before running examples.

1. Prepare the environment and model ID

The protocol documentation uses claude-sonnet-4-6. This is a documentation example, not a guarantee of current availability. Copy the current ID or documented alias exactly; do not add or remove prefixes yourself.

Use Bash on macOS, Linux or WSL, curl 7.76 or newer, and Python 3.10 or newer for reading saved responses. No third-party Python packages are required. Set the key in the same terminal:

bash
export TIKWAY_API_KEY='YOUR_TIKWAY_API_KEY'

2. Save the request and response

Save as 03-claude-request.json. The downloadable JSON has the same structure and a Chinese prompt:

json
{
    "model": "claude-sonnet-4-6",
    "max_tokens": 1024,
    "messages": [
        {
            "role": "user",
            "content": "Explain the role of an API gateway in an application in three sentences."
        }
    ]
}

Run in that file’s directory. This sends a real model request and saves the JSON body and headers separately, under your account’s billing rules.

bash
: "${TIKWAY_API_KEY:?Set the Tikway API Key environment variable first}"

curl --fail-with-body --silent --show-error \
  --connect-timeout 10 --max-time 60 \
  --request POST 'https://api.tikway.ai/v1/messages' \
  --header 'Content-Type: application/json' \
  --header "x-api-key: ${TIKWAY_API_KEY}" \
  --header 'anthropic-version: 2023-06-01' \
  --data-binary '@03-claude-request.json' \
  --dump-header 'claude-response.headers' \
  --output 'claude-response.json'

anthropic-version selects the protocol version; model selects the model. --data-binary @file preserves UTF-8 JSON and avoids complex quoting for long messages. --fail-with-body returns a nonzero code for HTTP errors while retaining the body. Check curl’s result before reading the answer: network failures can leave empty or partial files.

Headers may include x-request-id. Keep it for troubleshooting. Avoid sharing debug output containing authentication headers, or committing private response files to a public repository.

3. Extract text from the content array

This fabricated response illustrates multiple content blocks; it is not a real API result:

json
{
    "content": [
        { "type": "text", "text": "First paragraph." },
        { "type": "text", "text": "Second paragraph." }
    ],
    "stop_reason": "end_turn",
    "usage": { "input_tokens": 100, "output_tokens": 40 }
}

Read blocks where type == "text". Tool-use and thinking blocks have other fields and should not be converted indiscriminately into answer text.

Save this as 03-read-claude-response.py. The downloadable reader uses the same logic, with Chinese diagnostics. It only reads a local file:

python
"""Read a saved Anthropic Messages JSON response locally; no API calls."""

import json
from pathlib import Path
import sys


def extract_text(response):
    if not isinstance(response, dict):
        raise ValueError("Response must be a JSON object.")
    if response.get("error"):
        raise ValueError("Response contains an error; check the HTTP status and response headers.")
    blocks = response.get("content")
    if not isinstance(blocks, list):
        raise ValueError("Response has no content array.")
    text = "".join(
        block["text"] for block in blocks
        if isinstance(block, dict) and block.get("type") == "text"
        and isinstance(block.get("text"), str)
    )
    if not text:
        raise ValueError(f"No text blocks; stop_reason={response.get('stop_reason', 'unknown')}")
    return text


def main():
    path = Path(sys.argv[1] if len(sys.argv) > 1 else "claude-response.json")
    response = json.loads(path.read_text(encoding="utf-8"))
    print(extract_text(response))
    reason = response.get("stop_reason")
    if reason == "max_tokens":
        print("Note: output limit reached; the answer may be truncated.", file=sys.stderr)
    elif reason == "tool_use":
        print("Note: the model requested a tool; the application must handle tool_use blocks.", file=sys.stderr)


if __name__ == "__main__":
    try:
        main()
    except (OSError, ValueError, UnicodeError) as exc:
        print(f"Read failed: {exc}", file=sys.stderr)
        sys.exit(1)

Read the saved response:

bash
python 03-read-claude-response.py claude-response.json

max_tokens signals possible truncation. tool_use requires the application to process tool blocks. If there is no text, the script reports a reason instead of presenting an empty successful answer.

4. Add system instructions and conversation history

Put system instructions in the root system field, not a role: "system" message. These fields should be merged into the complete request from section 2, keeping its model and max_tokens. The assistant text is a fabricated example:

json
{
    "system": "Be concise. Explain the concept, then give an example.",
    "messages": [
        { "role": "user", "content": "What is an API?" },
        { "role": "assistant", "content": "An API is an interface for exchanging data or calling functions between programs." },
        { "role": "user", "content": "Illustrate this with a weather lookup." }
    ]
}

Include the needed history in later requests; do not assume the server remembers the previous one.

Field What to verify
max_tokens The example uses 1024; confirm the model’s range and inspect stop_reason.
system Root string or supported content-block structure; this example uses a string.
temperature / top_p Check support and permitted combinations before adding them.
stream Set true only when supported; the response becomes SSE and this JSON reader is unsuitable.

Troubleshoot common errors

Symptom First checks
Authentication failure A Tikway key is set and sent in x-api-key.
Unknown model or unsupported endpoint Exact catalog ID and Anthropic support.
Wrong path /v1/messages, without duplicated /v1.
Rejected message structure Nonempty messages, user/assistant roles, root system instructions.
429 Error details distinguishing low balance from rate limits.
No text blocks Stop reason, errors and non-text blocks such as tool_use.
Unreadable JSON file Curl result, file location and whether streaming was enabled.

Record model ID, status, usage and request ID to reduce unnecessary repeat calls. The operator states that it supplies the requested model; response model fields or a model’s self-description alone do not provide independent identity verification.

Continue with Claude Code setup, 401 troubleshooting and billing checks. Protocol references currently in Chinese: Anthropic · Authentication · Error codes.