curl --request POST \
--url https://ndi-api.nace.ai/v1/workspaces/{workspace_id}/upload-grants \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"max_bytes": 2,
"path": "<string>",
"total_size_bytes": 1,
"ttl_seconds": 3600
}
'{
"expires_at": "2023-11-07T05:31:56Z",
"token": "<string>",
"upload_url": "<string>"
}{
"error": {
"code": "invalid_request",
"detail": null,
"message": "Request body has extra fields that this operation does not accept.",
"request_id": "req-01j9k2n3p4q5r6s7t8v9",
"retryable": false
}
}{
"error": {
"code": "invalid_request",
"detail": null,
"message": "Request body has extra fields that this operation does not accept.",
"request_id": "req-01j9k2n3p4q5r6s7t8v9",
"retryable": false
}
}create_upload_grant
Mint a short-lived grant an end client redeems to upload directly. Cost class: fast.
The customer’s backend holds the API key; the end user’s browser must
never see it. This mints an HMAC-signed token that authorizes exactly one
thing — upload_file into this workspace, optionally pinned to one
destination path and a byte cap — until expires_at. The holder sends
it in the X-Upload-Token header of a multipart POST to
upload_url, so the bytes travel end-client → NDI once instead of
end-client → customer → NDI twice.
The grant is stateless (no DB row); its short TTL stands in for revocation, except that revoking the minting API key kills its outstanding grants immediately. Where the deployment runs Redis the grant is additionally single-use.
curl --request POST \
--url https://ndi-api.nace.ai/v1/workspaces/{workspace_id}/upload-grants \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"max_bytes": 2,
"path": "<string>",
"total_size_bytes": 1,
"ttl_seconds": 3600
}
'{
"expires_at": "2023-11-07T05:31:56Z",
"token": "<string>",
"upload_url": "<string>"
}{
"error": {
"code": "invalid_request",
"detail": null,
"message": "Request body has extra fields that this operation does not accept.",
"request_id": "req-01j9k2n3p4q5r6s7t8v9",
"retryable": false
}
}{
"error": {
"code": "invalid_request",
"detail": null,
"message": "Request body has extra fields that this operation does not accept.",
"request_id": "req-01j9k2n3p4q5r6s7t8v9",
"retryable": false
}
}Authorizations
Path Parameters
Workspace identifier.
Body
Body for POST /workspaces/{workspace_id}/upload-grants.
Every field narrows what the grant's holder may do; an empty body mints a grant for one upload anywhere in the workspace with the default TTL.
Per-grant byte cap, tighter than the service-wide NDI_MAX_UPLOAD_BYTES. Omit for the service cap.
x >= 1Pin the upload to exactly this destination path. Omit to let the holder choose.
1 - 1024^[^/]Exact expected upload size frozen into the grant. Distinct from max_bytes: a short body is rejected even when it fits under the cap.
x >= 0How long the grant verifies, in seconds.
1 <= x <= 3600Response
Successful Response
A minted upload grant, ready to hand to an end client.
The holder sends token in the X-Upload-Token header of a multipart
POST to upload_url (the workspace's upload_file route). The
grant authorizes that one method only, and is single-use where the
deployment runs Redis.