Skip to content
Esc
navigateopen⌘Jpreview
On this page

Migrate to the Responses API

Decide when an existing native SVG integration should adopt the Responses API and migrate its request and result handling.

Use POST /v1/responses with a model whose catalog entry includes open_responses. Responses lets your application declare functions or custom tools, handle the returned calls, and send results back for another turn. Native SVG endpoints remain the simpler choice for a known SVG operation.

Choose the right contract

Need Recommended API
Generate, vectorize, edit, or animate an SVG The corresponding native /v1/svgs/* endpoint
Let Arrow choose among functions your application provides /v1/responses with declared tools and tool_choice: "auto"
Request a specific caller function /v1/responses with tool_choice: { "type": "function", "name": "write_file" }
Continue after executing a tool /v1/responses, replaying messages, calls, and matching tool results

Native endpoints remain supported; migration is conditional, not a prerequisite for existing integrations.

SDK compatibility

Responses uses the Open Responses wire format. Compatibility covers the supported HTTP Responses surface, not every OpenAI endpoint or SDK feature.

Client Configuration
Vercel AI SDK Prefer @ai-sdk/open-responses with the complete https://api.quiver.ai/v1/responses URL. Streaming and non-streaming tool loops are supported.
OpenAI JavaScript and TypeScript SDK Set baseURL: "https://api.quiver.ai/v1", provide your QuiverAI API key, and use client.responses.create. Use the Responses API rather than Chat Completions.

For Vercel AI SDK integrations, configure the provider on your server:

import { createOpenResponses } from "@ai-sdk/open-responses";

const apiKey = process.env.QUIVERAI_API_KEY;
if (!apiKey) throw new Error("Set QUIVERAI_API_KEY before creating the provider.");

const quiver = createOpenResponses({
  name: "quiver",
  url: "https://api.quiver.ai/v1/responses",
  apiKey,
});
const model = quiver("arrow-2");

Confirm model access before using this configuration. With any SDK, disable stored responses and response-ID continuation, and avoid options that add include, background, or hosted tools. Some OpenAI-specific reasoning options add unsupported fields; prefer the Open Responses provider when integrating through Vercel AI SDK.

TanStack Start is an application framework, not a separate model protocol. Call these clients from server-side code in a TanStack Start application and keep the API key out of browser code.

Current limitations

The following limits apply regardless of which SDK sends the request:

Feature Current behavior
Transport HTTP with a JSON response or SSE streaming. WebSockets are not supported.
Response storage and retrieval Stateless requests only. Omit store or send store: false; there is no stored-response retrieval endpoint.
Conversation continuation Replay the full conversation input, including prior messages, returned calls, matching tool results, and opaque reasoning IDs. Omit previous_response_id or send null; response-ID continuation is not supported.
Tools Declare function or custom tools and execute them in your application. Hosted tools, including old quiver:* tools, are not supported.
Other options background, include, websocket, and unknown top-level fields are rejected.

store: true, a non-null previous_response_id, and unsupported request fields return 400 invalid_request before model execution. Organization data policy cannot enable these features. Stateless Responses behavior is separate from metadata and inference-retention policy; see Data controls.

Before migrating

  1. Call GET /v1/models and choose a model whose supported_operations includes open_responses. The catalog describes organization availability; the key must separately allow the model.
  2. Use a key whose authority permits Model catalog and Responses (catalog_read) and your chosen model. Native SVG capability authority is not required for a Responses call. The sandbox does not serve /v1/responses, so a Test key answers 404 there — see Sandbox and test keys.
  3. Read the model’s live billing.rates. Each Responses request in a tool loop can incur token charges; keep a limit on the number of requests your application makes.

Map the request

A native generation request names the operation in its URL and returns the generated SVG. A Responses request declares tools that your application implements. write_file below is an application-defined function, not a hosted filesystem service. Save this body as request.json:

{
  "model": "arrow-2",
  "input": "Create a minimal geometric compass icon in blue and stage it as compass.svg using write_file.",
  "tools": [
    {
      "type": "function",
      "name": "write_file",
      "description": "Stage compass.svg content for the caller to save after refinement is complete.",
      "parameters": {
        "type": "object",
        "properties": { "path": { "type": "string" }, "content": { "type": "string" } },
        "required": ["path", "content"],
        "additionalProperties": false
      },
      "strict": false
    }
  ],
  "tool_choice": { "type": "function", "name": "write_file" },
  "stream": false,
  "store": false,
  "parallel_tool_calls": false
}

Send one turn with cURL:

curl --fail-with-body https://api.quiver.ai/v1/responses \
  --header "Authorization: Bearer $QUIVERAI_API_KEY" \
  --header 'Content-Type: application/json' \
  --data @request.json \
  --output response.json

This command receives the model’s response; it does not execute a tool or finish a multi-turn integration. The Quickstart includes a complete bounded tool loop.

Old quiver:* hosted-tool definitions and their result.data[].svg receipts are not this contract. See Current limitations when adapting an existing client.

Map the result

Native JSON responses return final SVGs in data[].svg. Responses can return function_call, custom_tool_call, and assistant message items in output. A function call contains a name, call_id, and JSON-encoded arguments, for example:

{
  "type": "function_call",
  "id": "fc_1",
  "call_id": "call_1",
  "name": "write_file",
  "status": "completed",
  "arguments": "{\"path\":\"compass.svg\",\"content\":\"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\"/>\"}"
}

Validate the function name and arguments before handling it. Restrict file destinations in your application; never execute arbitrary paths or commands from model output.

Continue the tool loop

After handling a function call, append the relevant prior messages, the function_call item, and a function_call_output whose call_id matches it. For the staging function above, the result is:

{
  "type": "function_call_output",
  "call_id": "call_1",
  "output": "{\"path\":\"compass.svg\",\"staged\":true}"
}

Preserve returned opaque reasoning IDs in their original history order as { "type": "reasoning", "id": "<returned-id>" }; do not send private reasoning text or request encrypted reasoning. Send the history as input with the same model and tool definitions. Use tool_choice: "auto" on follow-up turns so the model can finish without another call. Custom tools use custom_tool_call_output with the corresponding call_id.

A completed tool call is not necessarily the last revision of an asset. Publish the latest staged content only after a completed response has no pending calls. An exhausted request limit, failed response, or incomplete response must not publish staged content as finished work. Do not use reasoning text as an artifact.

For streaming integrations, collect function-argument or custom-input deltas, then handle complete calls from the terminal response. Do not execute partial arguments. See Errors and debugging for terminal failure handling.

Roll out safely

Keep the native path available while validating the Responses path for an authorized project and key. Compare final SVG handling, token-usage accounting, timeout behavior, and retry policy before routing production traffic. A test key cannot validate /v1/responses; use a narrowly authorized Production key.

Was this page helpful?