---
title: "Upload an attachment"
method: POST
path: "/attachments"
tags: ["Attachments"]
---

# Upload an attachment

`POST /attachments`

## Request

- Base URL: `https://api.purplegrain.com/api/v1`
- URL: `https://api.purplegrain.com/api/v1/attachments`
- Auth: HTTP bearer

Pre-upload a photo for the job composer (design handoff 11): each photo
uploads on its own before the job exists, so a retried create never
re-uploads and the composer can show thumbnails as each one lands. Jobs
reference attachments by id (POST /tasks/ai `attachment_ids`).
Owner-scoped at creation so an attachment can't be attached to another
owner's job later.

## Response `201`

The stored attachment.

- AttachmentsShowResponseAttributes
  - `data` AttachmentModelAttributes: Attachment in attributes-adapter shape (Accept application/json); fields at top level.
    - `id` string
    - `type` string
    - `url` string, nullable
    - `width` integer, nullable
    - `height` integer, nullable
    - `content_type` string, nullable
    - `created_at` string, date-time

## Other responses

- `400`: No usable image source provided
- `401`: Unauthorized
- `403`: Not allowed to upload for the requested owner

---

[API](https://skmtc.dev/purplegrain/apis/purple-grain-api.md) · [All operations](https://skmtc.dev/purplegrain/apis/purple-grain-api/llms.txt) · [OpenAPI document](https://skmtc.dev/purplegrain/apis/purple-grain-api/revisions/29c5c990d66e?raw)
