# Genaro complete developer reference > Genaro is managed content and generative AI infrastructure for applications and agent-built workflows. It provides isolated workspaces, durable media assets, managed image and video generation, signed webhook events, usage attribution, and prepaid billing through an HTTP API. Canonical OpenAPI contract: https://genaro.ai/openapi.yaml Human-readable documentation and API reference: https://genaro.ai/docs#api-reference Quickstart: https://genaro.ai/docs#quickstart ## Purpose Use Genaro when a product needs content storage or generative image and video operations without building GPU scheduling, provider adapters, job durability, metering, and asset delivery. Customers consume the hosted API. Customers do not receive or run the Genaro infrastructure repository. Genaro does not need to know the customer's downstream users. ## Base URL and authentication Production base URL: `https://api.genaro.ai/api/v1` Send a workspace API key as a Bearer token: `Authorization: Bearer gn_live_...` Keep API keys server-side. Do not expose keys in browser JavaScript, mobile binaries, public source code, or logs sent to third parties. Every API key belongs to exactly one workspace. Authentication resolves that workspace and its parent infrastructure account. Request parameters cannot override either boundary. A key from one workspace cannot read an identifier owned by another workspace. ## Resource model Infrastructure account: - Represents the direct Genaro customer. - Owns the shared prepaid balance. - Contains one or more workspaces. Workspace: - Is a customer-controlled isolated tenant. - Owns API keys, assets, annotations, generations, webhook and telemetry endpoints, events, and attributed usage. - Is a logical grouping and reporting boundary, not a prescribed development or production environment. Tenant: - Is an optional customer-defined string inside a workspace. - Can represent the customer's own user, team, project, or customer. - Is indexed for filtering and returned for attribution. - Is not an identity principal, authorization boundary, separate balance, or Genaro account. Metadata: - Is an optional customer-defined JSON object stored and returned unchanged. - Can contain identifiers such as `user_id`, `project_id`, and `org_id` plus other customer context. - Is not indexed or trusted for authorization, deduplication, scheduling, or billing. ## First generation List the available models before creating a generation: ```bash curl https://api.genaro.ai/api/v1/models \ -H "Authorization: Bearer $GENARO_API_KEY" ``` Every model in the list is executable. The initial text-to-image model is `krea-2` (`KREA 2`). Read `GET /models/krea-2` for its complete parameter schema. Then create the generation: ```bash curl https://api.genaro.ai/api/v1/generations \ -H "Authorization: Bearer $GENARO_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "krea-2", "tenant": "customer-42", "params": { "prompt": "A copper robot in a daylight studio", "aspect_ratio": "4:5", "resolution": "1.5k" }, "metadata": { "user_id": "user-42", "project_id": "project-7", "org_id": "org-3" } }' ``` A newly accepted operation returns HTTP 202. Every request creates a new generation unless it carries an `Idempotency-Key` that was already used. ## Generation lifecycle 1. Genaro authenticates the workspace API key. 2. Genaro validates the logical model and parameters and calculates a fixed price. 3. Genaro atomically creates the operation, debits the parent account balance, and records `generation.accepted`. 4. Genaro durably dispatches the operation to managed compute. 5. Provider callbacks advance the operation through submitted and running states. 6. Success creates a durable output asset and a successful usage record. 7. Failure records the infrastructure error and fully refunds the customer charge. 8. Genaro exposes each lifecycle event through the Event API and sends it to matching active webhook endpoints. 9. Genaro exports a Generation trace to each active Workspace OTLP/HTTP endpoint after success or failure. Generation statuses: - `pending` - `submitted` - `running` - `succeeded` (terminal) - `failed` (terminal) Customer-requested cancellation is not supported in v1. Accepted work runs until it succeeds or fails. ## Executable models Generated from the live catalog; `GET /models` returns the same models. ### KREA 2 Model ID: `krea-2` Media type: image Capabilities: text to image Availability: `preview`, executable KREA 2 text-to-image generation with optional LoRAs. Parameters: - `prompt`: required string. - `aspect_ratio`: optional string enum. Default: `"4:5"`. One of: `1:1`, `4:3`, `3:2`, `16:9`, `21:9`, `3:4`, `2:3`, `9:16`, `4:5`, `5:4`. - `character_lora`: optional object | null. Default: `null`. - `loras`: optional array of objects. Default: `[]`. - `resolution`: optional string enum. Default: `"1.5k"`. One of: `1k`, `1.5k`, `2k`. - `schedule`: optional string enum. Default: `"beta"`. One of: `linear`, `beta`. - `seed`: optional integer | null. Default: `null`. - `steps`: optional string enum. Default: `"8"`. One of: `8`, `10`, `12`, `14`, `16`. ### Genaro H3 Model ID: `minimax-h3` Media type: video Capabilities: text to video, image to video Availability: `preview`, executable Self-hosted MiniMax H3 joint video and audio generation. Parameters: - `prompt`: required string. - `aspect_ratio`: optional string enum. Default: `"9:16"`. One of: `1:1`, `4:3`, `3:2`, `16:9`, `21:9`, `3:4`, `2:3`, `9:16`, `4:5`, `5:4`. - `draft`: optional boolean. Default: `false`. - `duration`: optional integer. Default: `5`. - `end_image`: optional media input. Default: `null`. - `image`: optional media input. Default: `null`. - `interpolate`: optional boolean. Default: `true`. - `num_inference_steps`: optional integer enum. Default: `30`. One of: `10`, `30`, `50`. - `seed`: optional integer | null. Default: `null`. ### SeeDream v5 Pro Model ID: `seedream-v5-pro` Media type: image Capabilities: text to image Availability: `preview`, executable ByteDance flagship v5 text-to-image model. Parameters: - `prompt`: required string. - `aspect_ratio`: optional string enum. Default: `"1:1"`. One of: `1:1`, `1:2`, `2:1`, `1:3`, `3:1`, `2:3`, `3:2`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9`, `9:21`, `21:9`. - `output_format`: optional string enum. Default: `"png"`. One of: `jpeg`, `png`. - `resolution`: optional string enum. Default: `"2k"`. One of: `1k`, `2k`. ### Kling Video v3.0 Pro Model ID: `kling-video-v3-0-pro` Media type: video Capabilities: image to video Availability: `preview`, executable Kwai Kling v3.0 Pro image-to-video model with optional audio. Parameters: - `image`: required media input. - `cfg_scale`: optional number. Default: `0.5`. - `duration`: optional integer | string. Default: `5`. - `element_list`: optional array | null. Default: `null`. - `end_image`: optional media input. Default: `null`. - `multi_prompt`: optional array | null. Default: `null`. - `negative_prompt`: optional string | null. Default: `null`. - `prompt`: optional string | null. Default: `null`. - `shot_type`: optional string enum. Default: `"customize"`. One of: `customize`, `intelligent`. - `sound`: optional boolean | null. Default: `null`. ### Topaz Video Upscale Model ID: `topaz-video-upscale` Media type: video Capabilities: video to video Availability: `preview`, executable Topaz AI video upscaler with 1x, 2x, or 4x output scaling. Parameters: - `video`: required media input. - `upscale_factor`: optional string enum. Default: `"2"`. One of: `1`, `2`, `4`. ### Nano Banana Pro Model ID: `nano-banana-pro` Media type: image Capabilities: text to image Availability: `preview`, executable Google's text-to-image model with resolution-aware pricing. Parameters: - `prompt`: required string. - `aspect_ratio`: optional string enum. Default: `"1:1"`. One of: `1:1`, `3:2`, `2:3`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9`, `21:9`. - `output_format`: optional string enum. Default: `"png"`. One of: `png`, `jpeg`. - `resolution`: optional string enum. Default: `"2k"`. One of: `1k`, `2k`, `4k`. - `seed`: optional integer | null. Default: `null`. ### Kling Image v3 Model ID: `kling-image-v3` Media type: image Capabilities: text to image Availability: `preview`, executable Kwai Kling v3 text-to-image model. Parameters: - `prompt`: required string. - `aspect_ratio`: optional string enum. Default: `"16:9"`. One of: `16:9`, `9:16`, `1:1`, `4:3`, `3:4`, `3:2`, `2:3`, `21:9`. - `output_format`: optional string enum. Default: `"png"`. One of: `png`, `jpeg`, `webp`. - `resolution`: optional string enum. Default: `"2k"`. One of: `1k`, `2k`. - `shot_type`: optional string enum. Default: `"customize"`. One of: `customize`, `intelligent`. ### Z-Image Turbo Model ID: `z-image-turbo` Media type: image Capabilities: text to image Availability: `preview`, executable Fast, low-cost Tongyi Z-Image text-to-image model. Parameters: - `prompt`: required string. - `output_format`: optional string enum. Default: `"jpeg"`. One of: `jpeg`, `png`, `webp`. - `seed`: optional integer | null. Default: `null`. - `size`: optional string. Default: `"1024*1024"`. ### Topaz Image Upscale Model ID: `topaz-image-upscale` Media type: image Capabilities: image to image Availability: `preview`, executable Topaz Gigapixel image upscaler with 1x, 2x, or 4x output scaling. Parameters: - `image`: required media input. - `model`: optional string enum. Default: `"Standard V2"`. One of: `Standard V2`, `Low Resolution V2`, `Recovery V2`, `High Fidelity V2`, `Redefine`, `CGI`, `Text Refine`. - `upscale_factor`: optional string enum. Default: `"2"`. One of: `1`, `2`, `4`. Call `GET /models` or `GET /models/{model_id}` for the current catalog and parameter contracts. `GET /models` lists only models that can run (`executable: true`). `availability: preview` means the model runs and is priced but has no quality or latency guarantee yet. `GET /models?include_hidden=true` also returns entries that cannot run yet (`executable: false`, `availability: inventory`) and models held back from the public list. Submitting an `executable: false` entry returns `422 model_unavailable` and charges nothing; a held-back model that reports `executable: true` still accepts generations. ## Endpoint reference ### Models `GET /models` List discoverable logical models. `GET /models/{model_id}` Get one model's stable ID, media type, capabilities, availability, and provider-neutral parameter schema. Provider routing stays private. ### Generations `GET /generations` List recent generations in the authenticated workspace. Accepts optional `?tenant=` filtering. `POST /generations` Validate, price, debit, and submit managed generation work. Send an `Idempotency-Key` header (1-255 printable characters) to make a retry safe. The same key and the same body in the same workspace within 24 hours returns the original generation (202, response header `Idempotent-Replayed: true`) and charges nothing. The same key with a different body returns 422 `idempotency_key_reuse`. Failed requests are not remembered. Media inputs accept exactly one of these shapes: ```json {"image": {"asset_id": "018f350c-2685-7c0b-9baa-4a0d0d2466ad"}} ``` ```json {"image": {"url": "https://uploads.example.com/opening.png?signature=..."}} ``` An Asset must be ready and belong to the authenticated workspace. HTTPS URL inputs remain temporary and do not create Assets. `GET /generations/{generation_id}` Read current state, validated parameters, fixed price, customer attribution, terminal error, and output assets. ### Assets `GET /assets` List workspace assets. Accepts optional `?tenant=` filtering. `POST /assets` Create a pending asset and a short-lived direct upload request. Example request: ```json { "media_kind": "image", "filename": "reference.png", "mime_type": "image/png", "size_bytes": 482113, "tenant": "customer-42", "metadata": { "project_id": "project-7", "role": "reference" } } ``` `mime_type` and `size_bytes` are required. Allowed types: image/png, image/jpeg, image/webp, image/avif, image/gif; video/mp4, video/quicktime, video/webm; audio/mpeg, audio/wav, audio/mp4, audio/ogg. Size limits: 50 MiB image, 2 GiB video, 200 MiB audio. Anything else is refused with 422 `validation_error`. Upload the bytes with the returned presigned R2 request, sending the `upload.headers` (Content-Type and Content-Length) exactly as given. Then call the completion endpoint. An upload not completed within one hour is deleted. `GET /assets/{asset_id}` Read one workspace asset. `POST /assets/{asset_id}/complete` Verify the uploaded object, record authoritative size and content type, and mark the asset ready. If the bytes are not the declared type or break the size limit, the response is 422 `upload_rejected` and the asset is failed and its object deleted. `GET /assets/{asset_id}/download` Return a short-lived direct download URL for a ready asset. ### Groups Groups are typed, ordered, editable lists of Assets. Use them for collections, generation candidate sets, variants, albums, sequences, and reference sets. Group membership organizes Assets and does not imply lineage. `GET /groups` List the authenticated Workspace's Groups and their ordered Assets. `POST /groups` Create a Group. `type` is required; `name`, `metadata`, and the initial ordered `asset_ids` list are optional. ```json { "type": "variant_set", "name": "Landing page explorations", "asset_ids": [ "018f350c-2685-7c0b-9baa-4a0d0d2466ad", "018f350c-2685-7c0b-9baa-4a0d0d2466ae" ] } ``` `GET /groups/{group_id}` Read one Group. The response returns `asset_ids` and expanded `assets` in membership order. `PATCH /groups/{group_id}` Update the Group's type, name, or metadata without changing its membership. `PUT /groups/{group_id}/assets` Atomically replace the complete ordered membership list. Invalid, duplicate, or cross-Workspace Asset IDs leave the existing list unchanged. Send an empty array to clear the Group. `DELETE /groups/{group_id}` Delete the Group and its memberships without deleting any Assets. ### Annotations `GET /assets/{asset_id}/annotations` List the append-only results attached to one Asset. `POST /assets/{asset_id}/annotations` Attach a caption, score, label, region, note, or other independent result to an Asset. ```json { "type": "caption", "data": {"text": "A cyclist crossing a wet city street"}, "source": "captioner-v3" } ``` `GET /annotations/{annotation_id}` Read one Annotation. Annotations stay separate so different tools and people can add results without rewriting the Asset or one shared Metadata object. ### Webhooks `GET /webhook_event_types` List the event types available for webhook subscriptions. `GET /webhook_endpoints` List the authenticated workspace's registered webhook destinations. `POST /webhook_endpoints` Register a public HTTPS destination. Select specific types with `event_types`; an empty array selects every available type. The create response is the only normal response that includes the initial `whsec_` signing secret. ```json { "url": "https://app.example.com/webhooks/genaro", "event_types": ["generation.succeeded", "generation.failed"] } ``` `GET /webhook_endpoints/{webhook_endpoint_id}` Read one webhook endpoint without its signing secret. `PATCH /webhook_endpoints/{webhook_endpoint_id}` Change the URL, description, event selection, or `active`/`disabled` status. `DELETE /webhook_endpoints/{webhook_endpoint_id}` Delete one webhook endpoint. `GET /webhook_endpoints/{webhook_endpoint_id}/deliveries` List the endpoint's delivery log, newest first. Filter with `status` (`pending`, `failed`, `delivered`, `dead`); paginate with `limit` and `cursor`. `POST /webhook_endpoints/{webhook_endpoint_id}/deliveries/{delivery_id}/replay` Re-send a `delivered` or `dead` delivery with its original `webhook-id`. Returns 202; a delivery still being retried (or whose last attempt is still finishing) returns 409. `POST /webhook_endpoints/{webhook_endpoint_id}/rotate_secret` Replace the signing secret. The response includes the new secret. Initial event types: - `generation.accepted` - `generation.submitted` - `generation.running` - `generation.succeeded` - `generation.failed` Genaro sends the selected events as HTTPS POST requests. Deliveries include `webhook-id`, `webhook-timestamp`, and `webhook-signature`. Verify `v1,` using HMAC-SHA256 over `webhook-id.webhook-timestamp.raw_body` and the decoded `whsec_` secret. Reject timestamps more than five minutes from the current time and compare the signature in constant time against the exact raw body before parsing JSON. Destinations must use HTTPS and resolve to public addresses. Genaro rejects private, loopback, link-local, carrier-grade NAT, multicast, reserved, and credential-bearing URLs, resolves the host once per attempt and connects to the validated address, and does not follow redirects. Return a 2xx response after accepting a delivery; any other response is retried with exponential backoff for about 24 hours (8 attempts) and then marked `dead`. `webhook-id` is the event id and is the same on every retry and replay, so deduplicate on it. An endpoint that accumulates five dead deliveries in a row is disabled and reports `disabled_reason`; every endpoint reports `last_failure`. After a terminal event, `GET /generations/{generation_id}` returns the full output Assets or failure details. ### Events `GET /events` List the Workspace's durable generation lifecycle Events. Optional filters are `tenant`, `operation_id`, and `type`. `GET /events/{event_id}` Read one lifecycle Event. ### OpenTelemetry `GET /telemetry_endpoints` List the Workspace's OTLP/HTTP trace destinations. `POST /telemetry_endpoints` Register the complete HTTPS trace-ingest URL supplied by an observability provider, normally ending in `/v1/traces`. ```json { "url": "https://otlp.example.com/v1/traces", "headers": {"Authorization": "Bearer collector-secret"}, "service_name": "my-product" } ``` Header values are stored as sensitive data and never returned. Responses include only `header_names`. `GET /telemetry_endpoints/{telemetry_endpoint_id}` Read one telemetry destination. `PATCH /telemetry_endpoints/{telemetry_endpoint_id}` Change the destination, headers, service name, or `active`/`disabled` status. Sending `headers` replaces the complete stored header object. `DELETE /telemetry_endpoints/{telemetry_endpoint_id}` Delete one telemetry destination. `GET /telemetry_endpoints/{telemetry_endpoint_id}/deliveries` List the endpoint's export log, newest first, exactly like webhook deliveries. `POST /telemetry_endpoints/{telemetry_endpoint_id}/deliveries/{delivery_id}/replay` Re-send a `delivered` or `dead` export. Failed exports are retried automatically with the same schedule as webhooks. After a Generation succeeds or fails, Genaro exports one `genaro.generation` Span with the Generation ID, Workspace ID, model, terminal status, and ordered lifecycle changes as Span events. Prompt text, customer Metadata, and media are not exported. ### Usage and balance `GET /usage` Return the parent account's current prepaid balance and successful usage records attributed to the workspace. Usage records carry optional tenant and metadata values. `GET /balance_transactions` Return immutable ledger entries attributed to the workspace, including generation charges and failure refunds. Account-level funding entries and sibling workspace transactions are excluded. ## Pricing and failure policy Generation pricing is fixed from the chosen model parameters and debited when the generation is accepted. If a generation fails, the customer receives a full refund even when Genaro incurred provider or execution cost. The API returns HTTP 402 when the shared parent account balance is insufficient or the account is past due. Storage charges will use the same prepaid balance. Storage policy includes a grace period, blocked content access after the grace period, and eventual deletion after an additional disclosed retention period. ## Limits - `tenant`: maximum 255 characters. - Generation prompt: maximum 20,000 encoded bytes. - Resource metadata: maximum 32,000 encoded bytes (422 `validation_error` above it). ## Errors Stable public errors never expose database or provider internals. Representative envelope: ```json { "error": { "type": "validation_error", "details": [{ "field": "prompt", "message": "must be at most 20000 encoded bytes" }] } } ``` Important status codes: - 200: successful read. - 201: asset, Annotation, webhook endpoint, or telemetry endpoint created. - 202: generation accepted. - 401: missing or invalid workspace API key. - 402: insufficient prepaid funds or past-due account. Agent turns need at least 0.05 USD of balance. `POST /conversations/{id}/messages` and `/tool-results` also accept `Idempotency-Key`: a retry returns the original agent turn without another model call. - 404: resource does not exist inside the authenticated workspace, or the id is not a valid UUID. Unknown routes use the same envelope. - 409: `idempotency_conflict`, a request with the same `Idempotency-Key` is still being processed; or a delivery cannot be replayed (still retrying) or its endpoint is disabled. - 422: request validation failed, including a `tenant` that is not a string or a malformed `generation_id` filter; also `idempotency_key_reuse`. Money is always `{"value": "0.065400", "currency": "usd"}`: a decimal string with six places. ## Integration invariants - A workspace API key cannot read or mutate another workspace. - The accepted generation price does not change after submission. - A terminal generation failure refunds the complete generation charge. - Tenant and metadata values are returned for attribution but do not grant authority. - Media upload and download URLs are short-lived. - Webhook deliveries are signed per endpoint and sent only for that endpoint's selected event types. - Failed webhook and telemetry deliveries are retried and replayable; `webhook-id` never changes for one event. - Telemetry header values are never returned through the API. - Customer-requested cancellation is not supported in v1. ## Deliberate v1 exclusions - Customer-requested cancellation. - Postpaid monthly invoicing. - Billing the customer's downstream users. - Customer-provided models or compute. - Arbitrary ComfyUI graph hosting. - Hosted Apps and agent runtime. - Batch discounts. ## Canonical links - Quickstart: https://genaro.ai/docs#quickstart - Human-readable API reference: https://genaro.ai/docs#api-reference - OpenAPI 3.1: https://genaro.ai/openapi.yaml - Concise LLM map: https://genaro.ai/llms.txt - Account sign-up: https://genaro.ai/sign-up