Promere API
REST endpoints for semantic prompt search, image reverse-engineering, and multi-model prompt formatting. Authenticate with a Bearer key from the dashboard.
Authentication
All authenticated endpoints expect a Bearer token in the Authorization header. Get a key from the dashboard— it's shown once at creation and never again.
bashcurl https://www.promere.app/api/v1/search \ -H "Authorization: Bearer pk_your_key_here" \ -H "Content-Type: application/json" \ -d '{"query": "neon-lit alley at midnight", "limit": 5}'
Keys start with pk_. Treat them like passwords — never commit them to source control or expose them in client-side code.
Rate Limits
Limits are per-endpoint, per-key, per UTC day. The response includes:
X-RateLimit-Limit— your daily capX-RateLimit-Remaining— calls left todayX-RateLimit-Reset— ISO timestamp of the next reset (midnight UTC)
| Tier | /search | /reverse | /format |
|---|---|---|---|
| Free | 20 | 5 | 20 |
When exceeded, the API returns 429 rate_limit_exceeded.
Error Format
All errors return a consistent JSON shape:
json{ "error": { "code": "rate_limit_exceeded", "message": "Daily search limit exceeded. Used 20/20. Resets at midnight UTC.", "limit": 20, "remaining": 0, "reset_at": "2026-05-12T00:00:00.000Z" } }
| Status | Code | Meaning |
|---|---|---|
| 400 | bad_request | Missing or invalid parameters |
| 401 | unauthorized | Missing, invalid, or revoked API key |
| 404 | not_found | Resource (e.g. prompt id) does not exist |
| 405 | method_not_allowed | Wrong HTTP verb for this endpoint |
| 429 | rate_limit_exceeded | Daily quota hit — wait until reset |
| 500 | internal_error | Unexpected server error — retry |
| 502 | analysis_failed | Upstream model call failed (reverse) |
| 503 | internal_error | Service not configured / unavailable |
POST /api/v1/search
Semantic search across the Promere prompt library. Returns prompts ranked by similarity.
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
query | string | yes | Natural-language search query |
limit | number | no | 1–40, default 10 |
| filters.category | string | no | Filter by primary category |
| filters.model | string | no | Filter by source model name |
Example request
bashcurl -X POST https://www.promere.app/api/v1/search \ -H "Authorization: Bearer pk_your_key_here" \ -H "Content-Type: application/json" \ -d '{ "query": "cinematic portrait in rain", "limit": 5, "filters": { "category": "Portrait & Headshot" } }'
Example response
json{ "results": [ { "id": "abc123", "prompt": "A portrait of a woman in heavy rain...", "model": "flux", "similarity": 0.82, "elements": { "subject": "A portrait of a woman in heavy rain", "action_pose": null, "setting": null, "lighting": "low-key, rim", "composition": "medium close-up", "style": "cinematic", "mood": "introspective", "technical": null }, "metadata": { "primary_category": "Portrait & Headshot", "sub_category": "Editorial", "visual_style": "cinematic", "lighting": "low-key, rim", "mood": "introspective", "composition": "medium close-up" } } ], "total": 1, "query": "cinematic portrait in rain" }
The elements object is built from existing classification metadata so you can pipe results straight into /api/v1/format. For a full 8-field structured parse of the prompt string, pass result.prompt to /api/v1/parse.
POST /api/v1/reverse
Analyze an image and reverse-engineer it into a structured 8-element prompt recipe. Accepts either a file upload (multipart/form-data) or a JSON body with an image_url. Max 10MB, JPEG/PNG/WebP.
Parameters — file upload
| Field | Type | Required | Description |
|---|---|---|---|
image | file | yes | JPEG, PNG, or WebP. Max 10MB. |
Parameters — URL
| Field | Type | Required | Description |
|---|---|---|---|
image_url | string | yes | Public http(s) URL. Fetched server-side with a 5s timeout. Must return a supported image content-type. |
Example — file upload
bashcurl -X POST https://www.promere.app/api/v1/reverse \ -H "Authorization: Bearer pk_your_key_here" \ -F "image=@/path/to/photo.jpg"
Example — URL
bashcurl -X POST https://www.promere.app/api/v1/reverse \ -H "Authorization: Bearer pk_your_key_here" \ -H "Content-Type: application/json" \ -d '{"image_url": "https://example.com/photo.jpg"}'
Example response
json{ "elements": { "subject": "A woman in her late twenties wearing a wet trench coat...", "action_pose": "Standing still, looking up into the rain...", "setting": "A narrow Tokyo alleyway at night...", "lighting": "Low-key with strong rim light from a neon sign...", "composition": "Medium close-up, 85mm equivalent, shallow DOF...", "style": "Cinematic photorealism with film grain...", "mood": "Melancholic and quietly resolute", "technical": "Shot on Sony A7IV, 85mm f/1.4, ISO 1600" }, "negative_prompt": "blurry, overexposed, distorted, watermark", "category": "Portrait & Headshot", "color_palette": ["#1a1f3a", "#d94e6e", "#f4c542", "#2c3e50", "#0a0a0f"] }
POST /api/v1/parse
Extract the 8-element structured recipe from a flat prompt string. Useful when you have a raw prompt (from your own data or from /api/v1/search) and want to retarget it at another model via /api/v1/format. Backed by Claude Haiku — cheap and fast.
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
text | string | yes | The prompt to parse. Max 4000 characters. |
Example request
bashcurl -X POST https://www.promere.app/api/v1/parse \ -H "Authorization: Bearer pk_your_key_here" \ -H "Content-Type: application/json" \ -d '{ "text": "a cinematic photo of a cyberpunk city at night, 8k, volumetric lighting, neon reflections on wet streets, wide angle" }'
Example response
json{ "elements": { "subject": "a cyberpunk city at night", "action_pose": null, "setting": "urban cyberpunk cityscape with wet streets", "lighting": "volumetric lighting, neon reflections", "composition": "wide angle", "style": "cinematic", "mood": "futuristic, atmospheric", "technical": "8K resolution" }, "negative_prompt": null, "category": "Landscape & Architecture" }
Counted against daily_format_limitin its own bucket (parse calls don't deplete /format's allowance).
POST /api/v1/format
Format an 8-element recipe into a model-specific prompt string. Pair with /api/v1/reverse to retarget any image at any supported model.
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
model | string | yes | Model id (see /api/v1/models) |
elements | object | yes | 8 string fields: subject, action_pose, setting, lighting, composition, style, mood, technical |
negative_prompt | string | no | Echoed back when model supports it |
Example request
bashcurl -X POST https://www.promere.app/api/v1/format \ -H "Authorization: Bearer pk_your_key_here" \ -H "Content-Type: application/json" \ -d '{ "model": "midjourney", "elements": { "subject": "A woman in a trench coat", "action_pose": "Looking up into the rain", "setting": "Tokyo alley at night", "lighting": "Neon rim light, low-key", "composition": "Medium close-up, shallow DOF", "style": "Cinematic photorealism", "mood": "Melancholic", "technical": "85mm f/1.4" } }'
Example response
json{ "formatted_prompt": "A woman in a trench coat, Looking up into the rain, Tokyo alley at night, Neon rim light, Cinematic photorealism, Melancholic --ar 16:9 --v 7 --s 500", "negative_prompt": null, "model": "midjourney", "model_info": { "name": "Midjourney", "family": "Midjourney", "prompt_style": "Short phrases + parameter flags", "ideal_length": "20–60 words", "supports_negative": true } }
GET /api/v1/models
List all supported model IDs and their prompt-style metadata. Public — no auth required.
Example request
bashcurl https://www.promere.app/api/v1/models
Currently supported
| id | Name | Family | Supports negative |
|---|---|---|---|
flux | Flux | Black Forest Labs | no |
| nano-banana-pro | Nano Banana Pro | Google (Gemini 3) | no |
| nano-banana-2 | Nano Banana 2 | Google (Gemini 3.1) | no |
| seedream-4.5 | Seedream 4.5 | ByteDance | yes |
| seedream-5-lite | Seedream 5 Lite | ByteDance | yes |
grok | Grok / Aurora | xAI | no |
midjourney | Midjourney | Midjourney | yes |
| stable-diffusion | Stable Diffusion | Stability AI | yes |
| dall-e | DALL-E / GPT Image | OpenAI | no |
ideogram | Ideogram | Ideogram | no |
GET /api/v1/prompts/{id}
Fetch a single prompt by its job_set_id.
Example request
bashcurl https://www.promere.app/api/v1/prompts/abc123 \ -H "Authorization: Bearer pk_your_key_here"
Example response
json{ "id": "abc123", "prompt": "A portrait of a woman in heavy rain...", "model": "flux", "thumbnail_url": "https://...", "dimensions": { "width": 1024, "height": 1024, "aspect_ratio": "1:1" }, "metadata": { "primary_category": "Portrait & Headshot", "visual_style": "cinematic", "lighting": "low-key, rim", "mood": "introspective", "composition": "medium close-up", "camera_simulation": "85mm f/1.4" }, "views": 1234 }
CORS
All /api/v1/* routes respond to OPTIONS preflight and include:
httpAccess-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS Access-Control-Allow-Headers: Authorization, Content-Type