API Documentation

Integrate AltFrame into your application with our REST API. Generate AI-powered alt text, titles, captions, and Open Graph descriptions for any image.

Single Generation

Synchronous. Process one image and receive results immediately.

Bulk Generation

Asynchronous. Submit up to 100 images and poll or receive a webhook.

Usage & History

Track credits, monitor usage, and browse generation history.

Base URL

All API endpoints are relative to the following base URL:

text
https://altframe.app

All requests must be made over HTTPS. HTTP requests will be rejected.

Authentication

All API requests require authentication using an API key. You can create and manage keys in the API Keys section of your dashboard.

Include your key in one of these request headers:

HTTP Headers
x-api-key: af_live_your_api_key

# or

Authorization: Bearer af_live_your_api_key

Keep your API key secret

Do not expose your API key in client-side code, public repositories, or browser network requests. Always call the AltFrame API from your server.

Quick Start

Generate alt text for an image with a single API call:

bash
curl -X POST https://altframe.app/api/v1/generate \
  -H "x-api-key: af_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "image_url": "https://example.com/photo.jpg",
    "mode": "standard",
    "language": "en",
    "keywords": ["organic gardening", "tomato seeds"],
    "max_length": 125,
    "fields": ["alt_text", "title", "caption", "og_description"]
  }'

Response

json
{
  "id": "job_abc123",
  "status": "completed",
  "results": {
    "alt_text": "Hands planting organic tomato seeds in rich dark soil in a raised garden bed",
    "title": "Planting Organic Tomato Seeds in Garden",
    "caption": "A gardener carefully plants organic tomato seeds into nutrient-rich soil in a raised bed.",
    "og_description": "Learn sustainable gardening with organic tomato seed planting techniques."
  },
  "meta": {
    "language": "en",
    "model": "gpt-4.1-nano",
    "tokens": { "input": 1180, "output": 142 },
    "processing_ms": 820,
    "credits_used": 1,
    "credits_remaining": 999
  }
}
POST/api/v1/generate

Generate alt text, title, caption, and OG description for a single image. The request is processed synchronously and the result is returned immediately.

Request Body

ParameterTypeRequiredDefaultDescription
image_urlstringRequired*Publicly accessible URL of the image to process.
image_base64stringRequired*Base64-encoded image data. Use this when the image is not publicly accessible.
modestringOptional"standard"Generation mode: "standard", "ecommerce", or "decorative".
languagestringOptional"en"ISO 639-1 language code for the generated text. Falls back to your account default language.
keywordsstring[]OptionalSEO keywords to naturally incorporate into the generated text.
max_lengthnumberOptional125Maximum character length for the alt text output.
page_urlstringOptionalURL of the page where the image appears. Provides additional context for more accurate results.
page_contextstringOptionalSurrounding text or heading near the image. Helps the AI understand the image's role on the page.
product_namestringOptionalProduct name for ecommerce mode. Most useful when mode is "ecommerce".
product_skustringOptionalProduct SKU or identifier for reference.
product_attributesRecord<string, string>OptionalKey-value pairs of product attributes (e.g. {"color": "red", "size": "large"}).
fieldsstring[]Optionalall fourWhich output fields to generate: "alt_text", "title", "caption", "og_description". Defaults to all four.
custom_promptstringOptionalCustom instructions appended to the AI prompt. Available on Tier 2 plans and above.

* One of image_url or image_base64 is required. If both are provided, image_url takes precedence.

Response 200 OK

json
{
  "id": "job_abc123",
  "status": "completed",
  "results": {
    "alt_text": "Hands planting organic tomato seeds in rich dark soil in a raised garden bed",
    "title": "Planting Organic Tomato Seeds in Garden",
    "caption": "A gardener carefully plants organic tomato seeds into nutrient-rich soil in a raised bed.",
    "og_description": "Learn sustainable gardening with organic tomato seed planting techniques."
  },
  "meta": {
    "language": "en",
    "model": "gpt-4.1-nano",
    "tokens": { "input": 1180, "output": 142 },
    "processing_ms": 820,
    "credits_used": 1,
    "credits_remaining": 999
  }
}
FieldTypeDescription
idstringUnique job identifier.
statusstring"completed" on success.
results.alt_textstringGenerated alt text for the image.
results.titlestringGenerated title / heading.
results.captionstringGenerated caption with more detail.
results.og_descriptionstringGenerated Open Graph description.
meta.languagestringLanguage used for generation.
meta.modelstringAI model used.
meta.tokens.inputnumberInput tokens consumed.
meta.tokens.outputnumberOutput tokens generated.
meta.processing_msnumberServer-side processing time in milliseconds.
meta.credits_usednumberCredits deducted for this request.
meta.credits_remainingnumberYour remaining credit balance.

Code Examples

bash
curl -X POST https://altframe.app/api/v1/generate \
  -H "x-api-key: af_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "image_url": "https://example.com/photo.jpg",
    "mode": "standard",
    "language": "en",
    "keywords": ["organic gardening", "tomato seeds"],
    "max_length": 125,
    "fields": ["alt_text", "title", "caption", "og_description"]
  }'
POST/api/v1/generate/bulk

Submit a batch of up to 100 images for asynchronous processing. Credits are reserved upfront. The API returns immediately with a batch_id that you can poll for status, or provide a webhook_url to be notified when the batch completes.

Request Body

ParameterTypeRequiredDefaultDescription
imagesobject[]RequiredArray of image objects (max 100). Each object can include the fields listed below.
modestringOptional"standard"Generation mode applied to all images: "standard", "ecommerce", or "decorative".
languagestringOptional"en"ISO 639-1 language code applied to all images.
keywordsstring[]OptionalSEO keywords applied to all images in the batch.
fieldsstring[]Optionalall fourOutput fields to generate for every image: "alt_text", "title", "caption", "og_description".
webhook_urlstringOptionalURL to receive a POST request when the batch finishes. See the Webhooks section below.

Image Object Fields

ParameterTypeRequiredDefaultDescription
image_urlstringRequired*Publicly accessible URL of the image.
image_base64stringRequired*Base64-encoded image data.
page_urlstringOptionalPage URL for context.
page_contextstringOptionalSurrounding text for context.
product_namestringOptionalProduct name (ecommerce mode).
product_skustringOptionalProduct SKU or identifier.
product_attributesRecord<string, string>OptionalKey-value product attributes.

* One of image_url or image_base64 is required per image.

Response 202 Accepted

json
{
  "batch_id": "b47ac10b-58cc-4372-a567-0e02b2c3d479",
  "total_images": 3,
  "credits_reserved": 3,
  "estimated_seconds": 6,
  "status_url": "/api/v1/batches/b47ac10b-58cc-4372-a567-0e02b2c3d479"
}
FieldTypeDescription
batch_idstring (UUID)Unique identifier for this batch.
total_imagesnumberNumber of images submitted.
credits_reservednumberTotal credits reserved for the batch.
estimated_secondsnumberEstimated processing time in seconds.
status_urlstringRelative URL to poll for batch status.

Code Examples

bash
curl -X POST https://altframe.app/api/v1/generate/bulk \
  -H "x-api-key: af_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "images": [
      {
        "image_url": "https://example.com/product-1.jpg",
        "product_name": "Organic Tomato Seeds",
        "product_sku": "SKU-TOM-001"
      },
      {
        "image_url": "https://example.com/product-2.jpg",
        "product_name": "Garden Trowel Set",
        "product_sku": "SKU-TRW-042"
      },
      {
        "image_url": "https://example.com/product-3.jpg"
      }
    ],
    "mode": "ecommerce",
    "language": "en",
    "keywords": ["gardening", "organic"],
    "fields": ["alt_text", "title"],
    "webhook_url": "https://yourapp.com/webhooks/altframe"
  }'
GET/api/v1/batches/:batch_id

Check the processing status of a batch. Returns completed results, in-progress counts, and any errors.

URL Parameters

ParameterTypeRequiredDefaultDescription
batch_idstring (UUID)RequiredThe batch_id returned from the bulk generation endpoint.

Response 200 OK

json
{
  "batch_id": "b47ac10b-58cc-4372-a567-0e02b2c3d479",
  "status": "completed",
  "total": 3,
  "completed": 3,
  "failed": 0,
  "results": [
    {
      "id": "job_def456",
      "image_url": "https://example.com/product-1.jpg",
      "results": {
        "alt_text": "Packet of organic heirloom tomato seeds with planting instructions",
        "title": "Organic Heirloom Tomato Seeds"
      },
      "meta": {
        "model": "gpt-4.1-nano",
        "tokens": { "input": 1024, "output": 96 },
        "processing_ms": 740
      }
    },
    {
      "id": "job_ghi789",
      "image_url": "https://example.com/product-2.jpg",
      "results": {
        "alt_text": "Three-piece stainless steel garden trowel set with ergonomic handles",
        "title": "3-Piece Garden Trowel Set"
      },
      "meta": {
        "model": "gpt-4.1-nano",
        "tokens": { "input": 980, "output": 88 },
        "processing_ms": 690
      }
    },
    {
      "id": "job_jkl012",
      "image_url": "https://example.com/product-3.jpg",
      "results": {
        "alt_text": "Wooden raised garden bed kit with soil and seedlings",
        "title": "Raised Garden Bed Starter Kit"
      },
      "meta": {
        "model": "gpt-4.1-nano",
        "tokens": { "input": 1100, "output": 102 },
        "processing_ms": 810
      }
    }
  ],
  "errors": []
}
FieldTypeDescription
batch_idstringThe batch identifier.
statusstring"processing", "completed", "partial", or "failed".
totalnumberTotal images in the batch.
completednumberNumber of successfully processed images.
failednumberNumber of images that failed processing.
resultsobject[]Array of completed results with id, image_url, results, and meta.
errorsobject[]Array of failed items with id, image_url, and error message.

Batch Status Values

StatusMeaning
processingOne or more images are still being processed.
completedAll images have been successfully processed.
partialProcessing is done but some images failed.
failedAll images in the batch failed.

Code Examples

bash
curl https://altframe.app/api/v1/batches/b47ac10b-58cc-4372-a567-0e02b2c3d479 \
  -H "x-api-key: af_live_your_api_key"
GET/api/v1/history

Retrieve your generation history with pagination. Results are ordered by creation date, newest first.

Query Parameters

ParameterTypeRequiredDefaultDescription
limitnumberOptional50Number of results per page (1 to 100).
offsetnumberOptional0Number of results to skip for pagination.
statusstringOptionalFilter by job status: "completed", "failed", "pending", or "processing".

Response 200 OK

json
{
  "jobs": [
    {
      "id": "job_abc123",
      "status": "completed",
      "image_url": "https://example.com/photo.jpg",
      "results": {
        "alt_text": "Hands planting organic tomato seeds in rich dark soil",
        "title": "Planting Organic Tomato Seeds",
        "caption": "A gardener plants tomato seeds into nutrient-rich soil.",
        "og_description": "Sustainable organic tomato seed planting techniques."
      },
      "mode": "standard",
      "language": "en",
      "meta": {
        "model": "gpt-4.1-nano",
        "tokens": { "input": 1180, "output": 142 },
        "processing_ms": 820,
        "cost_usd": 0.0004
      },
      "source": "api",
      "batch_id": null,
      "error": null,
      "created_at": "2025-07-15T10:30:00.000Z",
      "completed_at": "2025-07-15T10:30:00.820Z"
    }
  ],
  "pagination": {
    "total": 142,
    "limit": 10,
    "offset": 0,
    "has_more": true
  }
}
FieldTypeDescription
jobsobject[]Array of job objects.
jobs[].idstringUnique job identifier.
jobs[].statusstringJob status: "completed", "failed", "pending", "processing".
jobs[].image_urlstring | nullOriginal image URL (null if base64 was used).
jobs[].resultsobjectGenerated alt_text, title, caption, og_description.
jobs[].modestringGeneration mode used.
jobs[].languagestringLanguage used.
jobs[].metaobjectModel, tokens, processing_ms, cost_usd.
jobs[].sourcestring"api", "bulk", or "dashboard".
jobs[].batch_idstring | nullBatch ID if part of a bulk job.
jobs[].errorstring | nullError message if the job failed.
jobs[].created_atstringISO 8601 timestamp when the job was created.
jobs[].completed_atstring | nullISO 8601 timestamp when the job finished.
pagination.totalnumberTotal number of jobs matching your query.
pagination.limitnumberPage size used.
pagination.offsetnumberCurrent offset.
pagination.has_morebooleanWhether more results are available.

Code Examples

bash
curl "https://altframe.app/api/v1/history?limit=10&offset=0&status=completed" \
  -H "x-api-key: af_live_your_api_key"
GET/api/v1/usage

Check your current plan, credit balance, and overage settings. No request parameters required.

Response 200 OK

json
{
  "plan": "pro",
  "credits": {
    "monthly_allocation": 5000,
    "remaining": 4832,
    "rollover": 0,
    "used_this_period": 168,
    "period_resets_at": "2025-08-01T00:00:00.000Z"
  },
  "overage": {
    "enabled": true,
    "rate": 0.03
  }
}
FieldTypeDescription
planstringYour current plan name (e.g. "free", "starter", "pro", "business").
credits.monthly_allocationnumberTotal credits included in your plan per billing period.
credits.remainingnumberCredits remaining in the current period.
credits.rollovernumberUnused credits rolled over from the previous period.
credits.used_this_periodnumberCredits consumed so far this period.
credits.period_resets_atstringISO 8601 timestamp when credits reset (1st of next month UTC).
overage.enabledbooleanWhether overage billing is enabled on your account.
overage.ratenumberPrice per credit (USD) when exceeding your allocation.

Code Examples

bash
curl https://altframe.app/api/v1/usage \
  -H "x-api-key: af_live_your_api_key"

Webhooks

When submitting a bulk generation request, you can include a webhook_url parameter. AltFrame will send a POST request to that URL when the entire batch has finished processing.

How It Works

  1. Include webhook_url in your bulk generation request.
  2. AltFrame processes all images asynchronously.
  3. When the batch is fully complete (all images succeeded or failed), AltFrame sends a POST to your webhook URL.
  4. Your server should respond with a 2xx status code to acknowledge receipt.

Webhook Payload

json
// Your server receives a POST request when a batch completes:

POST https://yourapp.com/webhooks/altframe
Content-Type: application/json

{
  "event": "batch.completed",
  "batch_id": "b47ac10b-58cc-4372-a567-0e02b2c3d479",
  "status": "completed",
  "total": 3,
  "completed": 3,
  "failed": 0,
  "results": [
    {
      "id": "job_def456",
      "image_url": "https://example.com/product-1.jpg",
      "results": {
        "alt_text": "Packet of organic heirloom tomato seeds",
        "title": "Organic Heirloom Tomato Seeds"
      }
    }
  ],
  "errors": []
}

Example Handler

javascript
// Express.js webhook handler example

app.post("/webhooks/altframe", (req, res) => {
  const { event, batch_id, status, results, errors } = req.body;

  if (event === "batch.completed") {
    console.log(`Batch ${batch_id} finished: ${status}`);

    // Update your database with the generated alt text
    for (const item of results) {
      db.images.update({
        where: { url: item.image_url },
        data: {
          alt_text: item.results.alt_text,
          title: item.results.title,
        },
      });
    }

    // Handle any failures
    for (const err of errors) {
      console.error(`Failed: ${err.image_url} - ${err.error}`);
    }
  }

  res.status(200).json({ received: true });
});

Best Practices

  • Respond quickly (within 5 seconds) and process results asynchronously in your own queue.
  • Your webhook endpoint should be idempotent -- you may receive the same payload more than once on retry.
  • Use the batch_id to correlate webhook payloads with your original request.
  • If your server is unavailable, you can always poll the batch status endpoint as a fallback.

Rate Limits

Rate limits are applied per API key. When you exceed a limit, the API returns a 429 status code.

EndpointRate LimitWindow
POST /api/v1/generate60 requestsPer minute
POST /api/v1/generate/bulk10 requestsPer minute
GET /api/v1/batches/:batch_id120 requestsPer minute
GET /api/v1/history120 requestsPer minute
GET /api/v1/usage120 requestsPer minute

Rate Limit Headers

Every response includes headers to help you track your rate limit status:

HTTP Headers
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1700000060

Credit Costs

  • Standard image (JPEG, PNG, WebP): 1 credit
  • Advanced format (AVIF, HEIC, TIFF): 2 credits
  • Additional language: +1 credit

Handling 429 Errors

  • Wait until the X-RateLimit-Reset timestamp.
  • Use exponential backoff for retries.
  • For high-volume workloads, use the bulk endpoint instead.

Error Codes

All error responses return a JSON body with an error field describing the issue.

json
{
  "error": "Either image_url or image_base64 is required."
}

HTTP Status Codes

CodeNameDescriptionWhat to Do
400Bad RequestMissing or invalid parameters in the request body.Check the error message and fix the request payload.
401UnauthorizedInvalid, missing, or revoked API key.Verify your API key is correct and included in the x-api-key or Authorization header.
402Payment RequiredNo credits remaining and overage billing is disabled.Upgrade your plan, wait for credits to reset, or enable overage billing in your dashboard.
404Not FoundThe requested resource (e.g. batch) does not exist or does not belong to you.Verify the resource ID and that you are using the correct API key.
429Too Many RequestsRate limit exceeded for this endpoint.Wait for the rate limit window to reset. Use the X-RateLimit-Reset header.
500Internal Server ErrorAn unexpected error occurred on our servers.Retry the request with exponential backoff. If the error persists, contact support.

Need help?

If you encounter issues not covered here, contact us at support@altframe.ai with your request ID and error details.