Create attachment
POST /attachments. Parameters, permissions, request and response schemas.
POST /attachments
Create attachment. Requires the REST write token ability. The bearer token selects the Team; a supplied team_id cannot switch tenants. Additional role, entity-policy and plan requirements vary by operation. A Team in blocked billing mode cannot write and receives 402.
Authentication
Use a team API key as Authorization: Bearer YOUR_API_KEY. The token ability and the user’s role must both allow this operation. See authentication.
{
"ability": "write",
"team": "Token-bound Team",
"authorization": "Additional role, entity-policy and plan requirements vary by operation.",
"billing": "Blocked billing mode rejects writes with 402."
}Request body
A request body is required.
multipart/form-data
{
"type": "object",
"properties": {
"project_id": {
"type": "integer"
},
"name": {
"type": [
"string",
"null"
],
"maxLength": 255
},
"type": {
"type": "string",
"enum": [
"image",
"document",
"link"
],
"title": "AttachmentType"
},
"file": {
"type": "string",
"format": "binary",
"contentMediaType": "application/octet-stream",
"description": "Maximum file size: 10240 kilobytes."
},
"url": {
"type": "string",
"format": "uri",
"maxLength": 2048
},
"attachable_type": {
"type": "string",
"enum": [
"experiment",
"idea",
"insight",
"variation"
]
},
"attachable_id": {
"type": "integer"
}
},
"required": [
"project_id",
"type",
"attachable_type",
"attachable_id"
],
"title": "StoreAttachmentRequest",
"description": "For image/document attachments, file is required (up to 10 MB; JPEG, PNG, GIF, PDF, DOC/DOCX, XLS/XLSX). For link attachments, url is required. The linked record must exist in this Team.",
"allOf": [
{
"if": {
"properties": {
"type": {
"enum": [
"image",
"document"
]
}
},
"required": [
"type"
]
},
"then": {
"required": [
"file"
]
}
},
{
"if": {
"properties": {
"type": {
"const": "link"
}
},
"required": [
"type"
]
},
"then": {
"required": [
"url"
]
}
}
],
"example": {
"project_id": 101,
"type": "link",
"url": "https://example.com/research",
"attachable_type": "idea",
"attachable_id": 101
}
}{
"project_id": 101,
"type": "link",
"url": "https://example.com/research",
"attachable_type": "idea",
"attachable_id": 101
}Example request
For file fields, replace the synthetic local filename with an existing file of the documented type and size. Let curl set the multipart boundary.
curl --request POST 'https://api.example.test/api/attachments' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Accept: application/json' \
--form-string 'project_id=101' \
--form-string 'type=link' \
--form-string 'attachable_type=idea' \
--form-string 'attachable_id=101' \
--form-string 'url=https://example.com/research'Examples use fictional data. Replace resource IDs and the API host with your environment’s values.
Responses
200
AttachmentResource
Content type: application/json.
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"project_id": {
"type": "integer"
},
"name": {
"type": [
"string",
"null"
]
},
"file_type": {
"type": [
"string",
"null"
]
},
"file_size": {
"type": [
"integer",
"null"
]
},
"type": {
"type": "string",
"enum": [
"image",
"document",
"link"
],
"title": "AttachmentType"
},
"url": {
"type": [
"string",
"null"
]
},
"attachable_type": {
"type": "string"
},
"attachable_id": {
"type": "integer"
},
"created_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"updated_at": {
"type": [
"string",
"null"
],
"format": "date-time"
}
},
"required": [
"id",
"project_id",
"name",
"file_type",
"file_size",
"type",
"url",
"attachable_type",
"attachable_id",
"created_at",
"updated_at"
],
"title": "AttachmentResource"
}
},
"required": [
"data"
]
}{
"data": {
"id": 101,
"project_id": 101,
"name": null,
"file_type": null,
"file_size": null,
"type": "image",
"url": null,
"attachable_type": "example",
"attachable_id": 101,
"created_at": null,
"updated_at": null
}
}401
Unauthenticated
Content type: application/json.
{
"type": "object",
"properties": {
"message": {
"type": "string",
"description": "Error overview."
}
},
"required": [
"message"
]
}{
"message": "The request could not be completed."
}402
The Team is in read-only billing mode.
Content type: application/json.
{
"type": "object",
"properties": {
"error": {
"type": "string",
"const": "subscription_required"
},
"mode": {
"type": "string",
"const": "blocked"
},
"message": {
"type": "string",
"example": "Your team is in read-only mode. Update billing to make changes."
},
"grace_period_ends_at": {
"type": [
"string",
"null"
],
"format": "date-time"
}
},
"required": [
"error",
"mode",
"message",
"grace_period_ends_at"
]
}{
"error": "subscription_required",
"mode": "blocked",
"message": "Your team is in read-only mode. Update billing to make changes.",
"grace_period_ends_at": null
}403
Token ability, user permission, Team membership, plan, or billing mode does not allow this operation.
Content type: application/json.
{
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "This action is unauthorized."
}
},
"required": [
"message"
]
}{
"message": "This action is unauthorized."
}422
Validation error
Content type: application/json.
{
"type": "object",
"properties": {
"message": {
"type": "string",
"description": "Errors overview."
},
"errors": {
"type": "object",
"description": "A detailed description of each field that failed validation.",
"additionalProperties": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"required": [
"message",
"errors"
]
}{
"message": "The request could not be completed.",
"errors": {
"name": [
"The name field is required."
]
}
}429
Rate limit exceeded. Honor Retry-After before retrying.
Response headers:
{
"Retry-After": {
"description": "Seconds before retrying.",
"schema": {
"type": "integer"
}
}
}Content type: application/json.
{
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "Too Many Attempts."
}
},
"required": [
"message"
]
}{
"message": "Too Many Attempts."
}See API conventions for error handling, rate limits, pagination, and uploads.