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_projectPermissions: write

Endpoint

HTTP request

https://api.diffio.ai/v1/create_project

Use 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

FieldTypeRequiredDescription
fileNamestringYesOriginal file name for the upload.
contentTypestringNoMIME type for the upload. Defaults to application/octet-stream.
contentLengthnumberNoFile size in bytes, must be zero or higher.
fileFormatstringNoShort format label. When params.fileFormat is missing, this value is copied into it.
paramsobjectNoOptional parameters stored with the project.
params.fileFormatstringNoPreferred 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

FieldTypeRequiredDescription
apiProjectIdstringYesProject identifier for subsequent requests.
upload.uploadSessionIdstringYesIdentifier of this upload session.
upload.edgeBaseUrlstringYesBase URL of the upload API, for example https://media.diffio.io.
upload.uploadTokenstringYesBearer token for every upload API call in this session.
upload.objectKeystringYesStorage key the upload is written to.
upload.partSizeBytesnumberYesSize of every part except the last, in bytes (32 MiB).
upload.maxBytesnumberYesLargest file the session accepts, in bytes.
upload.expiresAtstringYesUpload session expiration timestamp in ISO 8601 format.
objectPathstringYesStorage key for the uploaded file, the same value as upload.objectKey.
expiresAtstringYesUpload 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.