ask2api is a minimal Python CLI tool that turns natural language prompts into structured API-style JSON responses using LLM.
It allows you to define a JSON Schema and force the model to answer strictly in that format.
Because LLMs are no longer just chatbots, they are also programmable API engines.
ask2api lets you use them that way. 🚀
Key features:
- Minimal dependencies
- CLI first
- Prompt → API behavior
- No markdown, no explanations, only valid JSON
- Vision modality support
- Designed for automation pipelines and AI-driven backend workflows
pip install ask2apiSet your API key:
export ASK2API_API_KEY="your_api_key"
# Or you can pass OpenAI key
# export OPENAI_API_KEY="your_api_key"ask2api supports both OpenAI (and OpenAI-compatible) and Anthropic (Claude) models.
By default, ask2api uses OpenAI. No additional configuration is needed:
export OPENAI_API_KEY="sk-..."
ask2api -p "What is 2+2?" -e '{"result": 1}'To use Anthropic's Claude models, set the provider explicitly:
export ASK2API_PROVIDER="anthropic"
export ANTHROPIC_API_KEY="sk-ant-..."
ask2api -p "What is the capital of France?" -e '{"country": "string", "city": "string"}'You can also customize the model:
export ASK2API_PROVIDER="anthropic"
export ASK2API_API_KEY="sk-ant-..."
export ASK2API_MODEL="claude-opus-4-5"
ask2api -p "Analyze carbon" -e '{"symbol": "string", "atomic_number": 1}'Anthropic's Claude models support vision as well:
export ASK2API_PROVIDER="anthropic"
export ANTHROPIC_API_KEY="sk-ant-..."
ask2api -p "What's in this image?" -e '{"description": "string"}' -i photo.jpgInstead of asking:
"Where is the capital of France?"
and receiving free-form text, you can do this:
ask2api -p "Where is the capital of France?" -sf schema.jsonOr pass an example directly without a schema file:
ask2api -p "Where is the capital of France?" -e '{"country": "string", "city": "string"}'And get a structured API response:
{
"country": "France",
"city": "Paris"
}For more complex structures with different data types:
ask2api -p "Analyze carbon element" -e '{
"symbol": "element symbol",
"atomic_number": 1234,
"atomic_weight": 12.34,
"is_metal": true,
"isotopes": ["name of the isotope"],
"properties": {
"melting_point": 1234.5,
"boiling_point": 2345.6,
"magnetic": true
}
}'Output:
{
"symbol": "C",
"atomic_number": 6,
"atomic_weight": 12.011,
"is_metal": false,
"isotopes": [
"C-12",
"C-13",
"C-14"
],
"properties": {
"melting_point": 3550,
"boiling_point": 4827,
"magnetic": false
}
}
You can also analyze images and get structured JSON responses:
ask2api -p "Where is this place?" -sf schema.json -i https://upload.wikimedia.org/wikipedia/commons/6/64/Lesdeuxmagots.jpgNote: Some API providers may not accept image URLs...
...and require images to be provided as base64-encoded data (i.e., a local file). If you encounter problems using an image URL, download the image locally and pass the file path, then ask2api will base64-encode local files automatically.
Example (download with curl and run):
curl -sSL -o place.jpg "https://upload.wikimedia.org/wikipedia/commons/6/64/Lesdeuxmagots.jpg"
ask2api -p "Where is this place?" -sf schema.json -i ./place.jpgOr download with wget:
wget -O place.jpg "https://upload.wikimedia.org/wikipedia/commons/6/64/Lesdeuxmagots.jpg"- You define the desired output structure using a JSON Schema.
- The schema is passed to the model:
- For OpenAI: using the
json_schemastructured output format - For Anthropic: using tool calling with forced tool use
- For OpenAI: using the
- The system prompt enforces strict JSON-only responses.
- For vision tasks, images are automatically encoded (base64 for local files) or passed as URLs.
- The CLI prints the API-ready JSON output.
The model is treated as a deterministic API function, regardless of provider.
Create a file named schema.json:
{
"type": "object",
"properties": {
"country": { "type": "string" },
"city": { "type": "string" }
},
"required": ["country", "city"]
}Contributions are welcome! Please feel free to submit a Pull Request.
MIT