Skip to content
Salyro
Tool

cURL to SDK code

Turn a cURL command into OpenAI, Anthropic or Google Gen AI SDK code in Python and TypeScript, and SDK code back into cURL. The key becomes a variable.

What it does

Paste a cURL command that calls a model, and get the same request as SDK code, in Python and in TypeScript:

  • OpenAI SDK (openai for Python and for Node): Chat Completions or Responses;
  • Anthropic SDK (anthropic, @anthropic-ai/sdk): Messages;
  • Google Gen AI SDK (google-genai, @google/genai): generate_content / generateContent.

The address decides which API the command is for: …/chat/completions, …/responses, …/v1/messages or …/models/{model}:generateContent. By default the code is for the same API. Choose another SDK, and the request goes through the LLM request converter first, with everything that did not carry over listed under the code.

Switch the direction to paste SDK code and get the cURL command it sends. Only a call whose values are written out is read: client.chat.completions.create(…), client.responses.create(…), client.messages.create(…) or client.models.generate_content(…). A variable, a function call, an f-string or a **spread in the arguments is refused with its line, because the tool never runs code. The same goes for the client's base URL: one read from a variable or the environment is an error, not a quiet switch to the provider's own address, because the tool cannot tell where the code sends its requests. The client's written-out headers, organization and project are carried.

Try it: an OpenAI command as OpenAI SDK code, the same command as Anthropic SDK code, a Gemini command, or Python code back to cURL.

The key

Whatever the command carries, the output reads the key from an environment variable:

  • Authorization: Bearer …, x-api-key: …, x-goog-api-key: … and Gemini's ?key=… are replaced by a variable. A key written into the command is not in the output, in the address of this page or in a share link.
  • A key that was already a reference, such as $OPENAI_API_KEY, keeps its variable. Otherwise the variable is the SDK's own (OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY), or one you name.
  • Other credentials, such as a cookie, -u user:password or a token-named header, are left out, and the tool says so.
  • Anything in the body that looks like a key is masked, and so is any text under a key's own name, such as api_key, token or password.
  • A base URL never keeps a query (?…), a fragment (#…) or a user and password, because a token can hide in each of them. They are left out, and the tool says so.

The share link holds the command or the code as the tool writes it back, with the key as a variable. If it cannot be written back, the link holds the settings only.

How it reads a command

It splits the command the way a POSIX shell would: single quotes, double quotes, $'…' quotes and lines continued with \. It reads -X, -H, -d, --data, --data-raw, --data-binary and --json, and bundled short options such as -sSd '{…}'. With -G, curl sends the data as a query on a GET, and -I asks for headers only. The tool says so rather than converting either, because the four APIs take a POST body. Variables are not expanded and nothing is run. A pipe, ; or redirection ends the command. A body read from a file (-d @body.json) cannot be seen from this page and is reported.

The code it writes

Each template was checked against one release of each SDK, named under the code with a link to the source it was read from. Python's SDK methods declare their keyword arguments. A field a method does not declare is sent in extra_body, which is how the SDKs take fields they do not name. For example, the Python Anthropic SDK 1.8.0 declares no temperature, so it goes there. In TypeScript the SDK sends the object as it is, and the tool says when the compiler would flag a field.

The Google Gen AI SDK takes a flat config rather than the REST body. The system instruction, tools and every generationConfig field sit side by side in it, where the SDK itself puts them. Gemini streams by method, so a streaming request calls generate_content_stream.

What it does not know

  • It does not run the code or send the request.
  • It writes Python and TypeScript only.
  • A command for another OpenAI-compatible address is read by its path, and the OpenAI SDK is pointed at its base URL. Whether that endpoint serves the request is for the endpoint to say.
  • A model id is carried as it was written. When you write for another provider's SDK, choose a model that provider serves.
  • It reads one request. A second call in the code, or a second address in the command, is left out.
  • A number too large to carry exactly, such as a 20-digit integer or 1e400, is reported. The output holds the nearest number, or null.
  • Long input is read in a background worker, so the page stays responsive.

Sources

The SDK templates were read from each SDK's source at the release named beside the code: openai-python 3.19.2, openai-node 7.23.0, anthropic-sdk-python 1.8.0, anthropic-sdk-typescript 0.128.0, python-genai 2.25.0 and js-genai 2.24.0. The request formats are the provider-format core's. Getting started shows the same call made to Salyro.

Where the numbers come from

This tool works only on what you enter. It uses no external data and runs entirely in your browser.