Calling the Sume API from Kotlin: no SDK, so write the poll loop
Sume publishes a TypeScript SDK and no Kotlin package. The documented submit, poll, fetch loop works from OkHttp or Ktor; the deadline lives in your client.

There is no official Kotlin client for the Sume API. The only published SDK is @sume-com/sdk for TypeScript, and the Sume docs say a Kotlin integration with OkHttp or Ktor follows the same three steps as any HTTP client. Hand-written is fine because the contract is small: submit with an idempotency key, poll status, fetch the result.
The three steps
The docs mark their Kotlin snippet as an illustrative sketch, not a package. Treat the steps as the contract.
| Step | Call | Stop condition |
|---|---|---|
| 1 Submit | POST /v1/{product}/generate with mode async and an Idempotency-Key | 202 with a job id |
| 2 Poll | GET /v1/jobs/{id}/status | terminal is true |
| 3 Fetch | GET /v1/jobs/{id}/result | Only when result_ready or completed |
Deadlines belong to the client
wait_timeout_seconds never exceeds 30 and bounds one HTTP request, not the job. Pick your own overall deadline; the docs call 20 minutes reasonable for video. Sleep next_poll_after_seconds when present and use exponential backoff otherwise. When your deadline passes, the job keeps running and billing, so persist the job id and either resume later from status_url or call cancel.
Typed models
Generate your data classes from the live OpenAPI at https://api.sume.com/reference/json rather than copying field tables from the docs; the docs themselves say the schema is the source of truth. Send exactly one credential header, either x-api-key or Authorization: Bearer, because sending both returns 401.
Sources
Related posts
More in Developers
- Kubb for the Sume OpenAPI spec: Zod schemas and SWR hooks
Kubb parses an OpenAPI spec once and feeds plugins for TypeScript, Zod and SWR. Here is how that maps to Sume's 3.0.3 spec, jobs and the polling stop rule.
- ky does not retry POST by default: Sume submit with a key
ky retries GET but not POST, and it also retries 413. How to configure it so a Sume submit retries safely and a too-large body fails fast.
- LangChain4j StreamableHttpMcpTransport: protocol detection for Sume
LangChain4j probes the MCP protocol on connect, which costs one round trip. Pin protocolVersion and set timeouts before pointing it at Sume's hosted MCP server.
- last_frame without first_frame returns 400: kling-3 and Seedance fix
A frame_images list with only a last_frame is rejected with 400 unsupported_capability. Send a first_frame too; Kling 3.0 uses start and end frames only.
Written by Sume