PortModels
Log in

Models

Listing available models and using the current chat, image, and video models.

List models#

text
GET /openai/v1/models
bash
curl https://api.portmodels.com/openai/v1/models \
  -H "Authorization: Bearer $PORTMODELS_API_KEY"
json
{
  "object": "list",
  "data": [
    {
      "id": "model-owner/example-model",
      "object": "model",
      "created": 1700000000,
      "owned_by": "model-owner",
      "root": "model-owner/example-model",
      "parent": null
    }
  ]
}

The id is the model key — the exact string to send as model in a chat completion. owned_by identifies the model's owner.

Get one model#

text
GET /openai/v1/models/{model_key}
bash
curl https://api.portmodels.com/openai/v1/models/model-owner/example-model \
  -H "Authorization: Bearer $PORTMODELS_API_KEY"

Model keys often contain a slash. The path accepts it directly, so no encoding is needed here.

Choosing a model#

  • Don't hard-code a single model forever. The catalogue changes; read the list at startup and fall back gracefully.
  • Match the model to the job. Most app work does not need the largest model available, and the price difference is large. See Pricing and markup.
  • Test cost, not just quality. Run the same realistic prompt through two candidates and compare usage.cost.

Model-specific usage#

The model catalog can change, so discover the current keys with GET /openai/v1/models. The following sections show the request shape for the currently published chat, image, and video models. A catalog entry does not mean every model uses the same endpoint: video jobs use the action API below.

DeepSeek V4.1 Flash#

Use the exact model key deepseek-v4.1-flash with the chat completions endpoint. It accepts normal text prompts and structured JSON requests:

bash
curl https://api.portmodels.com/openai/v1/chat/completions \
  -H "Authorization: Bearer $PORTMODELS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek-v4.1-flash",
    "messages": [
      {"role": "system", "content": "Return a concise answer."},
      {"role": "user", "content": "List three uses for a product brief."}
    ],
    "temperature": 0.2,
    "max_tokens": 300
  }'

For JSON output, set response_format and state the expected JSON shape in the messages:

json
{
  "model": "deepseek-v4.1-flash",
  "messages": [
    {"role": "system", "content": "Return JSON with a string field named summary."},
    {"role": "user", "content": "Summarize this text: ..."}
  ],
  "response_format": {"type": "json_object"}
}

Pruna p-image#

Use p-image with image generations. Ask for b64_json when your application wants image bytes directly; otherwise the response may contain a hosted url.

bash
curl https://api.portmodels.com/openai/v1/images/generations \
  -H "Authorization: Bearer $PORTMODELS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "p-image",
    "prompt": "A small blue ceramic cup on a white table, soft studio lighting",
    "n": 1,
    "size": "1024x1024",
    "response_format": "b64_json"
  }'

Read the generated image from data[0].b64_json and the metered amount from usage.cost. See Image generation for response handling and storage guidance.

For p-image, an explicit size must use WIDTHxHEIGHT with each dimension from 256 to 1440 pixels, in multiples of 16. 1024x1024 and 1440x816 are valid examples; 1792x1024 is not. The API does not resize an unsupported request automatically.

Pruna pruna-ai/p-image-edit#

Use pruna-ai/p-image-edit with the multipart image-edit endpoint. Upload the source image in the image field and describe only the change you want:

bash
curl https://api.portmodels.com/openai/v1/images/edits \
  -H "Authorization: Bearer $PORTMODELS_API_KEY" \
  -F "model=pruna-ai/p-image-edit" \
  -F "prompt=Remove the sign in the background and fill the wall naturally" \
  -F "[email protected];type=image/png" \
  -F "size=1024x1024" \
  -F "response_format=b64_json"

For pruna-ai/p-image-edit, choose exactly one of these size values:

Framesize
Square1024x1024
Landscape 4:31184x896
Portrait 3:4896x1184
Widescreen1376x768
Tall widescreen768x1376
Landscape 3:21248x832
Portrait 2:3832x1248

1792x1024 is not supported. For a wide edit, send size=1376x768.

For a model supporting multi-image uploads, repeat the upload as image[]. Input formats, output sizes, and image counts are model-specific; unsupported requests are rejected rather than silently converted to generation. The response uses the same data and usage.cost shape as image generation. See Image generation and editing for the multipart contract.

Grok Video 1.5: text, first-frame and reference images#

Use x-ai/grok-video-1.5 with ai.media.create at POST /run and a Connect token with models.run, an API key with video permission, or an account token. For first-frame generation, supply a public image URL in inputs.image; the tested request uses video_generation_mode: "first_frame_image_to_video", one second, and 480p. For reference generation, send inputs.reference_images and video_generation_mode: "reference_images_to_video". For text-only generation, use inputs: {} and video_generation_mode: "text_to_video". Poll with ai.media.get, then read the MP4 URL from job.result[0].url and the final charge from job.billing.settled_credits.

See Image-to-video for the complete authenticated example, credit reservation behavior, and troubleshooting. This flow is not available through /openai/v1/videos or the chat completions endpoint.

Seedance 1.0 Pro Fast: image-to-video#

Use bytedance/seedance-1.0-pro-fast with the same job API, placing source image URLs in inputs.image_urls. The low-cost configuration uses two seconds and 480p. See Seedance image-to-video for the complete request. Input field names differ between models.

Veo 3.1 Lite: text-to-video#

Use google/veo-3.1-lite with the same job API for the verified eight-second, 720p text-to-video configuration. Its parameters differ from Grok's; see Other video models.

Allowed models for published apps#

A published app has an allowed_models list. When your app runs models with a Connect token, that list applies — a model outside it is rejected even if it appears in /v1/models. Keep the list current as you change which models your app uses.