Skip to main content

Social Post Studio

Generate a ready-to-publish social post — image, caption and hashtags — in one call.

Overview

One call turns a topic into a post you can publish: an AI-generated image, a caption written for the platform, and a set of hashtags.

Endpoint: POST /v1/social/posts/generate

It composes the two metered surfaces it sits beside — image generation and the LLM — and bills as exactly that: the caption at the drafting model's token rate, the image at your chosen model's per-image rate. Both figures come back on every response.

  1. 1

    Your app

    Send a (and optionally a , and )

  2. 2

    CallMissed gateway

    Draft the caption and hashtags, then render the image

  3. 3

    Image model

    Produce the post image

  4. 4

    Your app

    Publish the caption, hashtags and image

Basic Usage

import requests

res = requests.post(
    "https://api.callmissed.com/v1/social/posts/generate",
    headers={"Authorization": "Bearer cm_your_key"},
    json={
        "topic": "our bakery's new sourdough, baked fresh at 6am",
        "platform": "instagram",
        "tone": "warm",
        "hashtag_count": 8,
        "image_model": "flux-2-klein-9b",
        "size": "1024x1024",
    },
).json()

print(res["caption"])
print(" ".join(res["hashtags"]))
# res["image"]["b64_json"] → base64 PNG
# res["credits"]["total"]  → what this post cost

Parameters

ParameterTypeDefaultDescription
topicstring—What the post is about. 3–2000 characters. Required.
platformstringgenericfacebook, instagram or generic. Sets the caption length ceiling and the voice.
tonestring—Optional voice, e.g. warm, professional, playful. Max 40 characters.
hashtag_countinteger8How many hashtags to return, 0–30. Instagram allows at most 30.
generate_imagebooleantrueSet false for a caption-only draft — no image credits, and no image key permission needed.
image_modelstringflux-2-klein-9bAny model from the image generation catalogue.
image_promptstring—An explicit prompt for the image. When omitted, the image prompt is written for you from the topic — see below. Max 4000 characters.
sizestring—Width×height for the image, e.g. 1024x1024, 1024x1280. Defaults to a 4:5 portrait, the ratio the Instagram and Facebook feeds prioritise.
qualitystring—For models that support it (GPT Image): low, medium, high or auto. Ignored by models without a quality tier.
reference_imagesstring[]—Up to 16 base64 PNG/JPEG images used as visual references, so the picture is built from your own logo or product shot. Requires gpt-image-2.5-sunburst, gpt-image-2.5-flare, gpt-image-2, gpt-image-1.5, nano-banana-2, nano-banana-pro or gemini-3.1-flash-lite-image.
reference_pdfstring—One base64 PDF. Its extracted text becomes brand context for the image prompt. Works with any image_model.
ninteger1Must be 1 — a post has one image. Any other value returns 422.
userstring—Your end user's id, for your own records.

Caption length follows the platform: 2,200 characters for instagram, 5,000 for facebook. generic uses the smaller of the two, so one draft is publishable on either.

Reference images and a brand PDF

Pass reference_images to put your real brand assets in the generated picture — a logo, a product shot, a packaging photo. The image is then produced as an edit of those references rather than a text-only generation, so the mark in the output is yours instead of an invented lookalike.

Each item is base64, either bare or as a full data:image/png;base64,… URL (what a browser's FileReader.readAsDataURL gives you, so no string surgery needed). PNG and JPEG only — the format is checked from the file's own bytes, not from a declared type. Up to 16 images, each at most 10 MB decoded (nano-banana-2, nano-banana-pro and gemini-3.1-flash-lite-image: up to 14 images, each at most 7 MB, 14 MB in total).

reference_pdf is a different kind of reference: a brand guideline, a spec sheet or a menu, whose text is extracted and folded into the image prompt as context. The file itself never reaches the image model, and a PDF with no extractable text (a scan) is ignored rather than failing the call. At most 10 MB decoded. Because only text reaches the model, it works with any image_model.

Reference images require an image model with an edit surface: gpt-image-2.5-sunburst, gpt-image-2.5-flare, gpt-image-2, gpt-image-1.5, nano-banana-2, nano-banana-pro or gemini-3.1-flash-lite-image. Sent with any other image_model, the request fails 422 before a single credit is reserved. That is deliberate — the alternative is quietly dropping your references and charging full price for a picture carrying none of your branding. For the same reason, a reference-carrying request will not silently fall back to a model that cannot honour them.

Pricing does not change on the gpt-image-* models. A referenced image is billed at exactly the same per-image rate as a plain generation of the same model, size and quality. nano-banana-2, nano-banana-pro and gemini-3.1-flash-lite-image add a small per-reference charge — see image pricing.

curl -X POST https://api.callmissed.com/v1/social/posts/generate \
  -H "Authorization: Bearer cm_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "topic": "our winter service package, booked till February",
    "platform": "instagram",
    "image_model": "gpt-image-2.5-sunburst",
    "reference_images": ["data:image/png;base64,iVBORw0KGgoAAAANS..."],
    "reference_pdf": "JVBERi0xLjQKJcfs..."
  }'

How the image prompt is written

When you don't pass image_prompt, the endpoint does not send your topic to the image model directly. A marketing topic ("winter tune-up, ₹1,200, booked until February") sent to an image model renders the words literally — garbled numbers, invented signage. Instead the caption drafter produces a separate, purely-visual prompt: it keeps the facts (prices, dates, your business name) in the caption, and describes a real, photographable scene for the image. The result is a photo that represents the offer rather than a picture trying to spell it out.

Pass your own image_prompt to override this and control the image directly.

Response

{
  "created": 1731234567,
  "topic": "our bakery's new sourdough, baked fresh at 6am",
  "platform": "instagram",
  "caption": "Pulled from the oven at 6am. Crackling crust, open crumb, still warm.",
  "hashtags": ["#sourdough", "#freshbread", "#bakery"],
  "image": {
    "b64_json": "<base64 PNG>",
    "revised_prompt": null,
    "url": "https://...signed-url..."
  },
  "model_used": "glm-4.7-flash",
  "image_model_used": "flux-2-klein-9b",
  "credits": {
    "image": 10.0,
    "llm": 0.065,
    "total": 10.065
  }
}
FieldDescription
captionThe drafted caption, already trimmed to the platform's limit.
hashtagsHashtags, each with its leading #. Empty when hashtag_count is 0.
imageb64_json plus a short-lived signed url. null when generate_image is false.
model_usedThe model that drafted the caption.
image_model_usedThe image model that actually served. null for a caption-only call.
creditsWhat you were charged, split by leg. total is the sum.

image.url is a short-lived signed link — download or re-host it promptly. The base64 payload in the same response has no expiry.

Generated images also appear in GET /v1/images/history alongside your other generations.

Permissions

CallRequired key permissions
generate_image: true (default)llm and image
generate_image: falsellm only

A key missing the permission for a leg gets 403 permission_denied before anything is generated or charged.

Pricing

Billed as two separate line items on your usage, at the same rates as calling the endpoints individually:

  • Caption + hashtags — per token, at the drafting model's rate. A typical post is well under one credit.
  • Image — the flat per-image price of image_model, plus any per-reference charge. See the image pricing table.

Every response carries the exact split in credits. A caption-only call is charged for the caption alone.

Image credits are reserved before generation and refunded in full if the post does not complete — and a request that fails is never charged for the caption either. A failed post costs nothing.

Errors

HTTPCodeMeaning
402insufficient_creditsBalance below the image cost. Top up in the dashboard.
403permission_deniedKey lacks llm (or image, when generating one).
403model_not_availableimage_model needs a paid plan.
404model_not_foundUnknown image_model.
422invalid_request_errorBad topic, platform or hashtag_count (0–30); n other than 1; a malformed or oversized reference_images / reference_pdf; or reference_images sent with an image_model that has no edit surface, or over its limits.
429quota_exceededMonthly plan cap hit for the LLM or image service.
429too_many_concurrent_requestsToo many in-flight requests on this key. Retry shortly.
503upstream_errorThe caption or the image failed. No credits charged — safe to retry.
503service_unavailableImage service temporarily unavailable. No credits charged.