Get It Done Logo
Get It Done

Start an attachment upload

POST/v1/tasks/{task_id}/attachments/uploads

Phase 1 of the two-phase upload (the SAME presign flow the in-app uploader uses): declares the file and answers a short-lived presigned PUT URL plus the `file_key` to register afterwards. Checked against the plan's file-size and storage allowances. Nothing is attached until phase 2. Supports the optional `Idempotency-Key` header (a replay returns the SAME URL, which may have expired — start a fresh upload instead of replaying old keys).

Required scopes
tasks:write
Availability
All plans
Quota cost
1 API call
Idempotency
Optional Idempotency-Key

Request

Path parameters

FieldTypeDescription
task_idrequiredstringTask short id, e.g. `T-123` (a bare `123` is also accepted on input).e.g. T-123

Request body

FieldTypeDescription
file_namerequiredstringe.g. screenshot.png
content_typerequiredstringe.g. image/png
sizerequiredintegerFile size in bytes — checked against the organization's plan file-size and storage allowances.
Raw request schema
{
  "type": "object",
  "properties": {
    "file_name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 255,
      "example": "screenshot.png"
    },
    "content_type": {
      "type": "string",
      "minLength": 1,
      "maxLength": 255,
      "example": "image/png"
    },
    "size": {
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991,
      "description": "File size in bytes — checked against the organization's plan file-size and storage allowances."
    }
  },
  "required": [
    "file_name",
    "content_type",
    "size"
  ],
  "description": "What you are about to upload."
}

Response 201

Where to PUT the file.

Fields

FieldTypeDescription
upload_urlrequiredstringPresigned URL — PUT the raw file bytes here (Content-Type must match what you declared).
upload_methodrequiredstring
file_keyrequiredstringOpaque storage key; pass it back when registering the attachment after the upload succeeds.
expires_atrequiredstring (date-time)When the upload URL stops working, ISO-8601 UTC.
Raw response schema
{
  "type": "object",
  "properties": {
    "upload_url": {
      "type": "string",
      "description": "Presigned URL — PUT the raw file bytes here (Content-Type must match what you declared)."
    },
    "upload_method": {
      "type": "string",
      "const": "PUT"
    },
    "file_key": {
      "type": "string",
      "description": "Opaque storage key; pass it back when registering the attachment after the upload succeeds."
    },
    "expires_at": {
      "type": "string",
      "format": "date-time",
      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
      "description": "When the upload URL stops working, ISO-8601 UTC."
    }
  },
  "required": [
    "upload_url",
    "upload_method",
    "file_key",
    "expires_at"
  ],
  "additionalProperties": false,
  "description": "Phase 1 of the two-phase upload: where to PUT the file."
}

Example request

curl
curl -X POST https://app.nowgetitdone.com/v1/tasks/T-123/attachments/uploads \
  -H "Authorization: Bearer gid_YOUR_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "file_name": "screenshot.png",
    "content_type": "image/png",
    "size": 1
  }'

Possible errors