# Sign one upload request (single PUT or one multipart step) for the caller's own attachment.

`POST /o/{org}/files/{id}/sign`

Only needed to re-sign an upload URL that expired, or to upload one file in parts;
`createFiles` already returns a ready single-shot `PUT` for each file. To re-sign that
single upload send `{"method": "PUT"}`; `GET` lists a multipart upload's parts and
needs its `upload_id`.
The body is @uppy/aws-s3's `signRequest` shape. `method` with `upload_id` and `part_number`
selects the operation: `PUT` (single upload), `PUT`+`upload_id`+`part_number` (upload part),
`POST` (create multipart), `POST`+`upload_id` (complete), `GET`+`upload_id` (list parts),
`DELETE`+`upload_id` (abort). `DELETE` without `upload_id` is refused with `403`. Signed URLs
last 60 seconds. Errors on this route use `{code, message}`, not `{error}`.

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `org` | path | string | yes | The org's slug or id. A caller with no role in the org gets `404`. |
| `id` | path | string | yes | File id from `createFiles`. |

## Request body

- `method` (string, required, one of `PUT`, `POST`, `GET`, `DELETE`)
- `upload_id` (string, optional)
- `part_number` (integer, optional): Only with `PUT` and `upload_id`.

## Example request

```bash
curl -X POST "https://api.prix.dev/o/$RUSH_ORG/files/$ID/sign" \
  -H "Authorization: Bearer $RUSH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "method": "PUT"
  }'
```

```typescript
const org = process.env.RUSH_ORG;
const id = process.env.ID;

const res = await fetch(`https://api.prix.dev/o/${org}/files/${id}/sign`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.RUSH_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    method: "PUT",
  }),
});

console.log(res.status, await res.json());
```

```python
import os

import requests

org = os.environ["RUSH_ORG"]
id = os.environ["ID"]

res = requests.post(
    f"https://api.prix.dev/o/{org}/files/{id}/sign",
    headers={"Authorization": f"Bearer {os.environ['RUSH_TOKEN']}"},
    json={
        "method": "PUT",
    },
)

print(res.status_code, res.json())
```

## Responses

### 200

One signed URL.

- `url` (string, required)
- `headers` (object, optional): Present for single PUT and create-multipart; the request must send exactly this content type.
  - `content-type` (string, required)

### 400

Malformed or unsupported combination (`INVALID_SIGN_REQUEST`).

### 401

No bearer, an unknown, revoked or expired one, or an API key on a route keys cannot call.

### 403

`DELETE` of the object is not signable (`DELETE_NOT_PERMITTED`).

### 404

No such attachment, or another user's (`NOT_FOUND`).

### 409

A run already holds the attachment (`ATTACHMENT_IN_USE`).

### 410

The attachment has expired (`ATTACHMENT_EXPIRED`).

## Example response (200)

```json
{
  "url": "https://example.com",
  "headers": {
    "content-type": "string"
  }
}
```
