Developers
Build photo intelligence into your product.
Be lazy. Use Phototology.
Composable AI analysis lenses. Deterministic Zod-validated JSON. Evidence chains on every conclusion. One API call.
Try It Now
Paste this. Get structured context back.
The sandbox key pt_test_sandbox returns fixture data instantly. No signup. No credit card. No rate limits.
curl -X POST https://api.phototology.com/v1/analyze \
-H "Authorization: Bearer pt_test_sandbox" \
-H "Content-Type: application/json" \
-d '{"imageUrl":"https://example.com/photo.jpg","preset":"full-analysis"}'Test keys return fixture data instantly. No signup required. Swap to a live key when you are ready for production.
Integration Surfaces
Four ways in. Same engine.
Claude Desktop / Claude Code
Add Phototology as a tool. Your agent can analyze photos without a vision model.
npx @phototology/mcp
Claude Desktop config:
{
"mcpServers": {
"phototology": {
"command": "npx",
"args": ["@phototology/mcp"],
"env": {
"PHOTOTOLOGY_API_KEY": "pt_test_sandbox"
}
}
}
}npm install @phototology/sdk
Typed client with built-in retries, error hierarchy, and streaming support.
import { PhototologyClient } from '@phototology/sdk';
const pt = new PhototologyClient({ apiKey: 'pt_test_sandbox' });
const result = await pt.analyze({
imageUrl: 'https://example.com/photo.jpg',
modules: ['dating', 'entities'],
});POST /v1/analyze
Send a photo and modules. Get structured JSON back. Works from any language.
POST https://api.phototology.com/v1/analyze
Authorization: Bearer pt_test_sandbox
Content-Type: application/json
{
"imageUrl": "https://example.com/photo.jpg",
"preset": "full-analysis"
}Interactive API Docs
Full OpenAPI spec with request/response schemas. Try endpoints directly from the browser.
GET https://api.phototology.com/v1/docs GET https://api.phototology.com/v1/openapi.json
Response Shape
Every response. Every surface. Same envelope.
Zod-validated. Deterministic. The shape never changes between modules, presets, or SDK versions.
{
"id": "an_...",
"object": "analysis",
"schemaVersion": "2.1.0",
"outputSchema": "photo",
"createdAt": "2026-04-29T12:00:00Z",
"output": { /* flat-keyed fields per requested lenses */ },
"usage": {
"inputTokens": 1847,
"outputTokens": 412,
"totalTokens": 2259,
"estimatedCostUsd": 0.03,
"modulesUsed": ["dating", "entities", "describe"],
"creditsCharged": 3
},
"warnings": [],
"meta": {
"processingTimeMs": 2340,
"provider": "gemini",
"model": "gemini-2.0-flash",
"vendor": "google",
"promptHash": "sha256:...",
"requestId": "req_abc123",
"ai_generated": true
}
}output
Module results keyed by module name. Only modules you request appear in the output.
usage
Token counts, cost estimate, and the list of modules that ran. Use this for billing reconciliation.
meta
Processing time, provider, prompt hash for reproducibility, and a unique request ID for support.
Error Handling
Built for agents. Every error tells you what to do.
Every error response includes a retryable boolean. Your agent never has to guess.
{
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded. Retry after 2 seconds.",
"retryable": true,
"requestId": "req_abc123"
}
}| Code | Meaning | Retryable |
|---|---|---|
400 | Bad request. Invalid modules, missing image, or malformed body. | No |
401 | Invalid or missing API key. | No |
403 | Key lacks permission for the requested operation. | No |
429 | Rate limit exceeded. Check the Retry-After header. | Yes |
500 | Internal server error. Something broke on our side. | Yes |
502 | Upstream provider error (vision model unavailable). | Yes |
Rate limit: 60 requests per minute on production keys. Sandbox keys have no rate limit. The Retry-After header is included on all 429 responses.
$0.01/lens. 1,000 free credits/month on signup.
Full analysis under $0.20/photo. Most use cases need 2-4 lenses. Re-analyzing a photo only bills lenses you have not run before. Lookups are free.
View pricingPhoto in. Context out.
1,000 free credits/month. No credit card. Sandbox key works right now.
Get your API key