API reference
Start an upload
POST /api/pub/v1/files/uploads, start a presigned multipart upload for a large file.
POST
https://api.dhanu.ai/api/pub/v1/files/uploadsStarts a presigned multipart upload. The response names the part size and one
PUT URL per part; upload each part directly to its URL, keep the ETag header
each PUT returns, then complete the upload.
The session expires after expiresInSeconds; an expired session must be started
again.
Request
| Field | Type | Required | Notes |
|---|---|---|---|
filename | string | Yes | At least 1 characters, up to 255 characters. |
mimeType | string | Yes | At least 1 characters. |
sizeBytes | integer | Yes | At least 0, at most 9007199254740991. |
curl -X POST https://api.dhanu.ai/api/pub/v1/files/uploads \
-H "Authorization: Bearer $DHANU_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "filename": "recording.mp4", "mimeType": "video/mp4", "sizeBytes": 734003200 }'const session = await dhanu.files.createUpload({
filename: "recording.mp4",
mimeType: "video/mp4",
sizeBytes: 734_003_200,
});
for (const part of session.parts) {
// PUT the matching byte range to part.url and keep the ETag header.
}session = dhanu.files.create_upload(filename="recording.mp4", mime_type="video/mp4", size_bytes=734_003_200)
for part in session.parts:
... # PUT the matching byte range to part.url and keep the ETag header Response
201 Created
{
"upload": {
"sessionId": "…",
"partSize": 8388608,
"partCount": 88,
"parts": [{ "partNumber": 1, "url": "https://…" }],
"expiresInSeconds": 3600
}
}
Errors
| Code | Status | Meaning |
|---|---|---|
invalid_api_key | 401 | The bearer key is missing or unknown. |
api_key_revoked | 401 | The key was revoked. |
api_key_expired | 401 | The key passed its expiry date. |
api_key_ip_not_allowed | 403 | The caller's IP is outside the key's allowlist. |
developer_access_revoked | 403 | The key's creator lost developer access in the workspace. |
api_key_project_scope | 403 | The key covers no active projects, or projectId is outside its scope. |
invalid_request_body | 422 | The body did not match the schema; error.issues names each field. |
unsupported_media_type | 415 | The file type is not accepted. |
file_too_large | 413 | The file is larger than the direct-upload limit. |
storage_quota_exceeded | 507 | The workspace's storage quota is full. |