MandAPI
English ▾
Integrations and templates

Describe objects in an image with MandAPI

Send a local image to a current Vision-capable model through Chat Completions.

Use this recipe with your coding assistant

Read the prompt
Add image understanding to my app using MandAPI Chat Completions at https://api.mandapi.com/v1/chat/completions. Read my existing backend and preserve its structure. Ask for an exact account-visible MODEL_ID with current Vision support. Keep MANDAPI_API_KEY on the server and submit text plus image_url content, using a correctly typed data URL for a local image. Start with an offline --demo request preview that makes no network calls. Prepare an explicit --live path for a single user-run image request and show where to inspect usage. State that the recipe is statically adapted and not a previously verified image-inference result. Return a short list of visible objects with uncertainty where appropriate; do not invent detection accuracy or exact measurements.
TXT

Choose a Vision-capable model

The current public MandAPI pricing metadata marks several enabled models as Vision. Choose an exact model ID available to your account from the current model list. Replace MODEL_ID below with that ID; a text-only model is not a substitute.

This is a compatibility recipe checked against current metadata and local request handling. No real image inference was run for this guide. Object descriptions can be uncertain; they are not guaranteed measurements or a tested detection benchmark.

Save a small request script

Use Python 3.10 or newer and save the following as vision.py. The key stays in your environment. The image is sent as a data URL, so the provider does not need to fetch a public image link.

python
import argparse
import base64
import json
import mimetypes
import os
from pathlib import Path
import urllib.error
import urllib.request

URL = "https://api.mandapi.com/v1/chat/completions"

def main():
    parser = argparse.ArgumentParser()
    mode = parser.add_mutually_exclusive_group(required=True)
    mode.add_argument("--demo", action="store_true")
    mode.add_argument("--live", action="store_true")
    parser.add_argument("--model", default="MODEL_ID")
    parser.add_argument("--image", type=Path)
    parser.add_argument("--language", choices=("en", "es"), default="en")
    args = parser.parse_args()

    image_url = "data:image/jpeg;base64,IMAGE_BYTES"
    if args.live:
        key = os.environ.get("MANDAPI_API_KEY")
        if not key or args.model == "MODEL_ID" or not args.image:
            parser.error("--live needs a private key, a real --model and --image")
        mime = mimetypes.guess_type(args.image.name)[0]
        if mime not in {"image/jpeg", "image/png", "image/webp"}:
            parser.error("Use a JPEG, PNG or WebP image")
        image_url = "data:" + mime + ";base64," + base64.b64encode(
            args.image.read_bytes()
        ).decode("ascii")

    payload = {
        "model": args.model,
        "messages": [{
            "role": "user",
            "content": [
                {"type": "text", "text": (
                    "Enumera los objetos visibles con una descripción breve. "
                    "Indica la incertidumbre; no deduzcas medidas exactas."
                    if args.language == "es" else
                    "List the visible objects and a short description. "
                    "Say when uncertain. Do not infer exact measurements."
                )},
                {"type": "image_url", "image_url": {"url": image_url}}
            ]
        }],
        "max_tokens": 300
    }
    if args.demo:
        print(json.dumps({"mode": "offline-preview", "request": payload}, indent=2))
        return

    request = urllib.request.Request(
        URL, data=json.dumps(payload).encode("utf-8"),
        headers={"Authorization": "Bearer " + key,
                 "Content-Type": "application/json"}
    )
    try:
        with urllib.request.urlopen(request, timeout=90) as response:
            result = json.load(response)
    except urllib.error.HTTPError as error:
        raise SystemExit("MandAPI HTTP " + str(error.code)) from None
    print(result["choices"][0]["message"]["content"])

if __name__ == "__main__":
    main()

Preview without making a request

bash
python vision.py --demo

This prints the request shape with a placeholder for the image bytes. It does not read a photo or call MandAPI. Pick a small, ordinary JPEG, PNG or WebP for your later live check.

Run with your own image

Set the key privately in the same terminal. In Bash:

bash
read -rsp "MandAPI key: " MANDAPI_API_KEY
printf '\n'
export MANDAPI_API_KEY

Or in PowerShell:

powershell
$env:MANDAPI_API_KEY = [Net.NetworkCredential]::new('', (Read-Host 'MandAPI key' -AsSecureString)).Password
bash
python vision.py --live --image photo.jpg --model MODEL_ID

The explicit --live command sends one chargeable model request. After you run it, compare the answer with the photo and find the corresponding MandAPI usage entry. Keep the API key on your backend if you integrate this into a web app.

Fix common failures

If the model rejects images, recheck its current Vision capability and the exact ID. A valid image extension does not repair corrupt image bytes; open the file locally and re-export it when needed. Check the selected model's image size and format requirements if it rejects a file. If a model rejects max_tokens, use that model's documented output-limit setting rather than inventing another field.

Ask for a list of visible objects or a short description first. Add structured extraction only after checking that the selected model follows your schema; do not promise precise bounding boxes from this example.

References

Topics inspired by public documentation; instructions and examples adapted for MandAPI.