API reference
Create project
Create a project and return an upload session for the original media. Review Diffio API behavior, response fields, setup details, and production workflows.
Create a project and return an edge upload session for the original media.
POST
/v1/create_projectEndpoint
HTTP request
https://api.diffio.ai/v1/create_projectUse POST with a JSON body.
Permissions
write
API keys must be active.
Authentication
Send the API key on every request using one of the supported headers.
Authorization: Bearer <apiKey>X-Api-Key: <apiKey>Xi-Api-Key: <apiKey>
Request
Send metadata for the file you plan to upload.
Body fields
| Field | Type | Required | Description |
|---|---|---|---|
fileName | string | Yes | Original file name for the upload. |
contentType | string | No | MIME type for the upload. Defaults to application/octet-stream. |
contentLength | number | No | File size in bytes, must be zero or higher. |
fileFormat | string | No | Short format label. When params.fileFormat is missing, this value is copied into it. |
params | object | No | Optional parameters stored with the project. |
params.fileFormat | string | No | Preferred format for downstream processing. |
cURL
curl -X POST "https://api.diffio.ai/v1/create_project" \ -H "Authorization: Bearer $DIFFIO_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "fileName": "song.wav", "contentType": "audio/wav", "contentLength": 1234567, "fileFormat": "wav", "params": { "fileFormat": "wav" } }'Response
Returns the project id and an upload session. Send the file to the session in parts; Diffio records the upload as soon as the session completes.
Response fields
| Field | Type | Required | Description |
|---|---|---|---|
apiProjectId | string | Yes | Project identifier for subsequent requests. |
upload.uploadSessionId | string | Yes | Identifier of this upload session. |
upload.edgeBaseUrl | string | Yes | Base URL of the upload API, for example https://media.diffio.io. |
upload.uploadToken | string | Yes | Bearer token for every upload API call in this session. |
upload.objectKey | string | Yes | Storage key the upload is written to. |
upload.partSizeBytes | number | Yes | Size of every part except the last, in bytes (32 MiB). |
upload.maxBytes | number | Yes | Largest file the session accepts, in bytes. |
upload.expiresAt | string | Yes | Upload session expiration timestamp in ISO 8601 format. |
objectPath | string | Yes | Storage key for the uploaded file, the same value as upload.objectKey. |
expiresAt | string | Yes | Upload session expiration timestamp in ISO 8601 format. |
Successful response
{ "apiProjectId": "proj-123", "upload": { "uploadSessionId": "api-proj-123", "edgeBaseUrl": "https://media.diffio.io", "uploadToken": "v1.eyJ0eXAiOiJ1cGxvYWQifQ.signature", "objectKey": "api/users/user-123/projects/proj-123/original/song.wav", "partSizeBytes": 33554432, "maxBytes": 2147483648, "expiresAt": "2025-01-06T12:35:10Z" }, "objectPath": "api/users/user-123/projects/proj-123/original/song.wav", "expiresAt": "2025-01-06T12:35:10Z"}Return codes
200Success, treated as complete.: Project created, upload session returned.204Success, treated as empty response.: CORS preflight when method is OPTIONS.400Bad request, treated as client error.: Invalid JSON body, fileName must be provided as a string, contentType must be a string, contentLength must be a number, contentLength must be zero or higher, params must be an object.401Unauthorized, treated as auth error.: Missing API key, or invalid API key.403Forbidden, treated as permission error.: API key is not active, or missing write permission.405Client error, treated as fix required.: Method is not POST.500Server error, treated as retryable.: API key not linked to an account, failed to create upload record, or failed to create upload session.
Notes
- fileName is required.
- contentLength is coerced to an integer, send whole bytes to avoid truncation.
- params can be null, it is treated as an empty object.
- fileFormat is expected to be a string, when provided and params.fileFormat is missing it is copied as is.
- objectKey uses the basename of fileName; characters other than letters, digits, spaces, parentheses, period, underscore, and hyphen are replaced with underscores, and an empty name becomes upload.
- Upload with the session: POST {edgeBaseUrl}/v1/uploads/start returns uploadId; PUT each part (at most partSizeBytes, numbered from 1) to {edgeBaseUrl}/v1/uploads/parts/{partNumber}?uploadId={uploadId}; then POST {edgeBaseUrl}/v1/uploads/complete with {uploadId, parts: [{partNumber, etag}]}. Send Authorization: Bearer {uploadToken} on every call.
- A failed part can be retried on its own. The official Python and JavaScript SDKs do all of this for you.
- The session expires at expiresAt; create a new project if it expires before the upload completes.
