# GET /api/v2/uploads/{upload}

Read an upload ticket

- MCP id: uploads.show
- Scope: api:read:project_management
- Scope: api:read:project_drive
- Scope: api:read:customer_drive
- Scope: api:read:organization_drive
- Scope: api:read:user_drive
- Permission: none, the record's own rules still apply
- Rate cost: 1 unit, read bucket.
- Cache-Control: private, no-store

Returns one of your own upload tickets: its status, the size and SHA-256 of the bytes the server actually received, the media type it detected from them, both deadlines and, while the ticket is still waiting for its bytes, the `upload_url` to PUT them to.

Use it to check whether an upload landed before registering it, or to recover the `media_id` of one already registered. A ticket belongs to the credential that created it: somebody else's ticket is `404`, and so is one whose permission family your token does not cover. No domain permission is required (the ticket is your own scratch object), but the parent record's write permission was checked when it was created and is checked again when it is registered. Tickets are hard-deleted, so `trashed` is not an accepted parameter, and a pruned one is `404`.

## Parameters
- upload (integer, path): The Upload's numeric id.
- view (string, optional): Which field set to render.
- X-Request-Id (header, optional): A correlation id of your own. It is recorded in our logs next to the server's request id but never returned: the response header always carries the server's id. A value that does not match the pattern is discarded silently, never rejected.
- If-None-Match (header, optional): The ETag a read is conditional on. A match is answered 304 with no body.

## Response 200
- id (integer, required): Unique identifier. Send this as `upload_id` when you register the bytes.
- work_item_id (integer or null, required): The work item this ticket attaches to, or `null` when it targets a drive item.
- drive_item_id (integer or null, required): The drive item this ticket attaches to, or `null` when it targets a work item.
- collection (string ≤ 255, required): The media collection the file will land in. Always `attachments`: it is chosen by the route, and no request field can change it.
- file_name (string ≤ 255, required): The sanitized file name the file will carry. Sent when the ticket is created; control characters are stripped and `#`, `/`, `\` and spaces become hyphens, so what you read back can differ from what you sent.
- byte_size (integer, required): The size you declared when creating the ticket. A declaration, not a bound: the server counts the bytes it actually receives.
- checksum_sha256 (string or null, required): The optional SHA-256 you declared when creating the ticket. When present the server refuses bytes that do not match it.
- received_byte_size (integer or null, required): The number of bytes that actually arrived, measured by the server. Null until the upload lands.
- received_checksum_sha256 (string or null, required): The SHA-256 the server computed over the bytes it received. Null until the upload lands.
- mime_type (string or null ≤ 255, required): The media type detected from the received bytes. Detected, never declared: the API accepts no content type when creating the ticket and ignores the `Content-Type` of the upload itself.
- status (string, required): Where the ticket is in its lifecycle.
- upload_url (string or null, required): Where to PUT the file. An opaque absolute URL: send the raw file as the body of a PUT whose only header is your Authorization bearer token. No `Content-Type` is read and the body is stored exactly as sent, so a form envelope would become part of the file. Present only while status is `pending`.
- expires_at (timestamp (YYYY-MM-DDThh:mm:ssZ), required): The deadline for the PUT. After it the ticket is dead and a new one must be created.
- register_by (timestamp (YYYY-MM-DDThh:mm:ssZ) or null, required): The deadline for the registration, set when the bytes land and measured from that moment, so a slow upload does not eat into the time you have to register. Null until the upload lands.
- uploaded_at (timestamp (YYYY-MM-DDThh:mm:ssZ) or null, required): When the bytes arrived. Null until they do.
- committed_at (timestamp (YYYY-MM-DDThh:mm:ssZ) or null, required): When the bytes became a file. Null until they do.
- media_id (integer or null, required): The id of the file this ticket became. Null until it is registered, and set exactly once.
- created_at (timestamp (YYYY-MM-DDThh:mm:ssZ), required): When the ticket was created.
- updated_at (timestamp (YYYY-MM-DDThh:mm:ssZ), required): Last-write timestamp; use for incremental sync.
- links (UploadLinks, required)
  - self (url, required): The canonical URI of this record.

## Errors
- 403 forbidden-by-policy | insufficient-permission | insufficient-token-scope: Forbidden.
- 304 : Not modified.
- 400 idempotency-key-required | invalid-cursor | invalid-query-parameter | malformed-request | unsupported-parameter: Bad request.
- 401 token-expired | unauthenticated: Unauthenticated.
- 404 endpoint-not-found | resource-not-found: Not found.
- 406 not-acceptable: Not acceptable.
- 429 rate-limit-exceeded: Too many requests.
- 500 internal-error: Server error.
- 503 tenant-unavailable: Service unavailable.

## Example
```bash
curl -X GET \
  'https://<your-url>/api/v2/uploads/1' \
  -H 'Authorization: Bearer <token>' \
  -H 'Accept: application/json'
```
