Synsema docsENES

Provider API directly

The built-in ops (reason/decide/…) cover most needs and keep you vendor-neutral. But when you need a parameter the ops don't expose (streaming, vision, a specific endpoint, your own retry logic), call the provider's HTTP API yourself. It's a normal HTTP request — so it's gated by net(host) and uses a secret for auth (see Secrets).

llm-api-direct.syn
-- Doc example: calling a provider's HTTP API directly (instead of the built-in ops).
-- It's a normal HTTP request, so it is gated by net(host) and uses secret/bearer for auth.
intent: "doc example: provider API directly"
require net("api.anthropic.com")
require secret("ANTHROPIC_API_KEY")

task call_undeclared_provider()
    -- api.openai.com is NOT declared → the request is denied at the capability check
    give http_post("https://api.openai.com/v1/chat/completions", {}, {"x-api-key": secret("ANTHROPIC_API_KEY")})

test "a direct provider call is gated by net(host) like any HTTP request"
    assert_error(call_undeclared_provider)

Anthropic (Messages API) — header is x-api-key, not Bearer

require net("api.anthropic.com")
require secret("ANTHROPIC_API_KEY")

let r be http_post("https://api.anthropic.com/v1/messages",
    {"model": "claude-sonnet-4-6", "max_tokens": 256,
     "messages": [{"role": "user", "content": "Say hi"}]},
    {"x-api-key": secret("ANTHROPIC_API_KEY"),        -- raw secret in a CUSTOM header
     "anthropic-version": "2023-06-01"})
let text be (((json of r)["content"])[0])["text"]

OpenAI / DeepSeek — Authorization: Bearer

require net("api.openai.com")
require secret("OPENAI_API_KEY")

let r be http_post("https://api.openai.com/v1/chat/completions",
    {"model": "gpt-4o", "messages": [{"role": "user", "content": "Say hi"}]},
    {"Authorization": bearer(secret("OPENAI_API_KEY"))})

The key is a secret: it materializes only at the socket and is redacted in logs/errors. When to use this vs. the built-in ops: the ops for portability and validated decisions; the direct API for provider-specific features. You give up vendor-neutrality and the automatic context/validation.