API surface
Create an API Key and start calling SeaLink. Each capability includes the minimal request, when to use it, and where to read the detailed guide.
API document scope
/api/openapi is the complete SeaLink OpenAPI 3.1 document. OpenAI SDKs work well with compatible paths such as /v1/chat/completions, /v1/responses, /v1/embeddings, and /v1/models; use the examples on this page to call media, task, realtime, account, and billing APIs directly over HTTP or WebSocket. Use /v1/models for the model list, /v1/pricing for prices, and /v1/capabilities for capability, parameter, and billing dimensions.
Call basics
Use https://api.sealink.io as the base URL. Send Authorization: Bearer $SEALINK_API_KEY on authenticated requests. Synchronous APIs return results directly; video and some generation jobs return a task id first, then you poll for status.
Media and vision inputs
Image editing, image-to-image, image-to-video, keyframe video, and vision embedding models accept data:image/...;base64,... inputs. You may also send a regular image URL when it is directly downloadable by the model service and both dimensions are greater than 10 px. Video generation returns an async task id; poll /v1/tasks/{task_id}. If submit returns 503 model_temporarily_unavailable, retry after the Retry-After window or switch to an available model; requests without a task id do not create a final usage charge. The video examples below use https://raw.githubusercontent.com/mathiasbynens/small/master/jpeg.jpg as a downloadable image input.
OpenAI-compatible chat completion endpoint. Use stream=true for streaming responses.
curl https://api.sealink.io/v1/chat/completions \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "claude-opus-5-5","messages": [{"role":"user","content":"Hello"}]}'
Use the chat endpoint with OpenAI-compatible image_url content. Choose a vision model from /v1/models; pass image_url.url as a public HTTPS URL or data URL, and use a real image larger than 10 px on both dimensions.
curl https://api.sealink.io/v1/chat/completions \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "claude-opus-5-5","messages": [{"role": "user","content": [{ "type": "text", "text": "Describe this image in one sentence." },{ "type": "image_url", "image_url": { "url": "https://example.com/photo.jpg" } }]}]}'
Use an embedding model from /v1/models for text. For Google gemini-embedding-2 multimodal embeddings, pass input as an object with text plus image, video, audio, pdf, or file_uri and use output_dimensionality when you need a shorter vector.
curl https://api.sealink.io/v1/embeddings \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "gemini-embedding-001","input": ["Hello", "您好", "สวัสดี"]}'
IMG_B64="$(base64 -w0 photo.png)"curl https://api.sealink.io/v1/embeddings \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "gemini-embedding-2","input": {"text": "catalog image for retrieval","image": "data:image/png;base64,'"$IMG_B64"'"},"output_dimensionality": 768}'
Rank candidate documents by relevance to a query for RAG, enterprise search, and post-retrieval refinement.
curl https://api.sealink.io/v1/rerank \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "<rerank-model-from-/v1/models>","query": "best API gateway for Qwen models","documents": ["SeaLink exposes one rerank API.","A sourdough starter needs regular feeding.","Rerank models improve retrieval quality for RAG."],"top_n": 2}'
Generate images from a prompt. Use size values such as 1024x1024; SeaLink will pass them to the selected model in the format it expects.
curl https://api.sealink.io/v1/images/generations \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "gpt-image-2","prompt": "A clean product photo of a white ceramic mug on a wooden desk","n": 1,"size": "1024x1024","response_format": "url"}'
Image editing models use this endpoint, not /v1/images/generations. Choose an image-edit model from /v1/models, then send image_url in JSON or upload a local image with multipart form data.
IMG_B64="$(base64 -w0 photo.png)"curl https://api.sealink.io/v1/images/edits \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "<image-edit-model-from-/v1/models>","image_url": "data:image/png;base64,'"$IMG_B64"'","prompt": "Replace the background with a bright studio backdrop","n": 1,"size": "1024x1024"}'
Upload a source image and create one or more variations.
curl https://api.sealink.io/v1/images/variations \-H "Authorization: Bearer $SEALINK_API_KEY" \-F "image=@photo.png" \-F "model=<image-variation-model-from-/v1/models>" \-F "n=2" \-F "size=1024x1024"
Increase image resolution from a URL or base64 input.
curl https://api.sealink.io/v1/images/upscale \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "<image-upscale-model-from-/v1/models>","image": "https://example.com/low-res.jpg","scale": 2}'
Apply a style reference image to an image.
curl https://api.sealink.io/v1/images/style-transfer \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "<image-style-transfer-model-from-/v1/models>","image": "https://example.com/photo.png","style_reference": "https://example.com/style.png","strength": 0.7}'
Remove the background from an image and return a transparent result.
curl https://api.sealink.io/v1/images/background-remove \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "<image-background-remove-model-from-/v1/models>","image": "https://example.com/photo.png"}'
Video generation is asynchronous. Submit a short task first, store the returned id and x-sealink-request-id, then poll the status endpoint. Use duration, size, image_url, and last_image_url in SeaLink requests; SeaLink sends the matching fields to the selected model. Check /v1/models for each model's supported video input mode and resolution; duration limits are model-specific. Submit-time 503 model_temporarily_unavailable responses are retryable and do not create a final usage charge when no task id is returned.
curl https://api.sealink.io/v1/video/generations \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "seedance-1-0-pro-fast","prompt": "A coffee cup on a desk, soft morning light, slow camera move","size": "1280x720","duration": 5,"n": 1}'
IMG_B64="$(base64 -w0 first-frame.png)"curl https://api.sealink.io/v1/video/generations \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "<image-to-video-model-from-/v1/models>","prompt": "A tiny product photo turning slowly on a clean table","image_url": "data:image/png;base64,'"$IMG_B64"'","size": "<supported-size-from-/v1/models>","duration": 5,"n": 1}'
curl https://api.sealink.io/v1/video/generations \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "<remote-image-to-video-model-from-/v1/models>","prompt": "A tiny product photo turning slowly on a clean table","image_url": "https://raw.githubusercontent.com/mathiasbynens/small/master/jpeg.jpg","size": "<supported-size-from-/v1/models>","duration": 3,"n": 1}'
FIRST_B64="$(base64 -w0 first-frame.png)"LAST_B64="$(base64 -w0 last-frame.png)"curl https://api.sealink.io/v1/video/generations \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "<keyframe-video-model-from-/v1/models>","prompt": "Smoothly move from the first frame to the last frame","image_url": "data:image/png;base64,'"$FIRST_B64"'","last_image_url": "data:image/png;base64,'"$LAST_B64"'","size": "<supported-size-from-/v1/models>","duration": 5,"n": 1}'
curl https://api.sealink.io/v1/tasks/task_abc123 \-H "Authorization: Bearer $SEALINK_API_KEY"
Edit an existing video with a prompt. The video URL must be directly downloadable by the model service. Wan animate models require both a video input and a reference image; the input video should contain exactly one clearly visible human body. Do not send a placeholder URL.
curl https://api.sealink.io/v1/video/edits \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "seedance-1-0-pro-fast","video": "<publicly-downloadable-video-url>","prompt": "Change the background to a beach sunset","resolution": "1280x720","duration": 5}'
IMG_B64="$(base64 -w0 character.png)"curl https://api.sealink.io/v1/video/edits \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "<video-animate-model-from-/v1/models>","prompt": "Make the subject wave gently","image_url": "data:image/png;base64,'"$IMG_B64"'","video_url": "<publicly-downloadable-single-person-video-url>","size": "<supported-size-from-/v1/models>","duration": 5,"n": 1}'
curl https://api.sealink.io/v1/video/edits \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "<video-edit-model-from-/v1/models>","function": "image_reference","prompt": "Use the reference image as the main subject","image_url": "https://raw.githubusercontent.com/mathiasbynens/small/master/jpeg.jpg","obj_or_bg": ["obj"],"size": "1280x720","duration": 5,"n": 1}'
Use WebSocket transport for realtime ASR, Omni, and TTS models. Plain HTTP requests return 426 because the client must send WebSocket Upgrade headers.
import WebSocket from "ws";const ws = new WebSocket("wss://api.sealink.io/ws/realtime?model=<realtime-model-from-/v1/models>",{ headers: { Authorization: `Bearer ${process.env.SEALINK_API_KEY}` } },);ws.on("message", (event) => {console.log(event.toString());});
Generate audio from text. Voice IDs are model-specific; check /v1/models model details before copying a voice into production.
curl https://api.sealink.io/v1/audio/speech \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "music-2.0","input": "Hello, welcome to SeaLink.","voice": "<voice-from-/v1/models>","response_format": "wav"}' \--output speech.wav
Transcribe audio. Use public audio-stt models from /v1/models; Alibaba ASR models support JSON file_url/file_urls and long ASR tasks return 202 for /v1/tasks polling.
curl https://api.sealink.io/v1/audio/transcriptions \-H "Authorization: Bearer $SEALINK_API_KEY" \-F "model=qwen3-asr-flash-filetrans" \-F "file_url=https://raw.githubusercontent.com/Jakobovski/free-spoken-digit-dataset/master/recordings/1_jackson_0.wav" \-F "response_format=json" \-F "language=en"
Upload audio and receive an English translation transcript.
curl https://api.sealink.io/v1/audio/translations \-H "Authorization: Bearer $SEALINK_API_KEY" \-F "file=@korean_speech.mp3" \-F "model=<audio-translation-model-from-/v1/models>"
Generate music from a prompt. Duration, style, and instrumental options depend on the model.
curl https://api.sealink.io/v1/audio/music \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "<audio-music-model-from-/v1/models>","prompt": "An uplifting orchestral piece with piano and strings","lyrics_prompt": "[Verse]\nMorning light across the city\n[Chorus]\nWe rise together","duration": 30,"instrumental": false}'
Generate a short sound effect from a natural-language description.
curl https://api.sealink.io/v1/audio/sound-effects \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "<audio-sfx-model-from-/v1/models>","prompt": "A soft notification chime","duration_seconds": 3}'
Provide a reference audio file or URL and text to synthesize in that voice. Use a public or private voice-clone model from your catalog snapshot.
curl https://api.sealink.io/v1/audio/voice-clone \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "<audio-voice-clone-model-from-/v1/models>","audio": "https://raw.githubusercontent.com/Jakobovski/free-spoken-digit-dataset/master/recordings/1_jackson_0.wav","text": "This is a SeaLink voice clone sample."}'
Check user input before sending it into generation flows. Accepts text strings and image content objects.
curl https://api.sealink.io/v1/moderations \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "<moderation-model-from-/v1/models>","input": "Please check this user message."}'
Public — no auth needed. Returns the OpenAI-format model list. Pricing units follow the model maker's native billing unit; for non-text models, read billing_unit, retail_unit_price, and pricing.metered_lines instead of treating input_per_1m/output_per_1m as the source of truth.
curl https://api.sealink.io/v1/models
Used by Claude Code and native Anthropic SDK clients. Auth via x-api-key or Authorization header. Official tool_choice objects, thinking, and output_config.effort are accepted when the selected model supports them.
curl https://api.sealink.io/anthropic/v1/messages \-H "x-api-key: $SEALINK_API_KEY" \-H "anthropic-version: 2023-06-01" \-H "Content-Type: application/json" \-d '{"model": "claude-opus-5-5","max_tokens": 256,"messages": [{"role":"user","content":"Hi"}],"tools": [{"name": "lookup_status","description": "Return a status string","input_schema": {"type":"object","properties":{}}}],"tool_choice": {"type": "any"},"output_config": {"effort": "low"}}'
Want more depth?
Error codes: /docs/error-codes. Rate limits: /docs/rate-limits. Streaming: /docs/streaming.
Validate an API Key and read its current balance, monthly budget, and RPM/TPM limits. Useful for CLIs and key health checks.
curl https://api.sealink.io/v1/me \-H "Authorization: Bearer $SEALINK_API_KEY"
Add `metadata.task_type` to your request body to tag a call with a business task ("translation", "summary", "support_reply", etc. — free-form, max 64 chars). SeaLink stores it on the usage_events row; you'll see spend rolled up by task on /dashboard/usage.
curl https://api.sealink.io/v1/chat/completions \-H "Authorization: Bearer $SEALINK_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "claude-opus-5-5","metadata": { "task_type": "translation" },"messages": [{"role": "user", "content": "..."}]}'
The metadata field does not affect model execution. Tagging is optional; calls without a tag work fine.
Create, rotate, and revoke API Keys. Keys are access credentials for your account — treat them like passwords.
Create a keySign in → /dashboard/keys → 'New API Key' → enter a name and optional monthly budget cap → Create. Keys start with sk-sealink-. The full key is shown once at creation and never again.
If a key may be compromised: create a new key → update your app config to use it → revoke the old key in /dashboard/keys. Revoked keys stop working immediately; in-flight requests complete. Rotate every 90 days as a best practice.
Find the key in /dashboard/keys → Revoke → confirm. Revocation is irreversible. All requests with that key will return 401 after revocation. Create a new key to resume access.