Posts
Photo posts
photo-service
Posts of up to twenty pictures (PHOTO_MAX_FILES), each with what it shows, and replies with pictures (photos.md).
One photo post
/photos/{id}Who: Anyone, signed in or not
Parameters
idintegerrequiredin pathThe post's id.
Answers
- 200OKMediumNode application/json
- 400the request is not well formed, or a value in it is not one it may be
- 403the viewer may not see it
- 404there is no such post
Request
curl "https://api.example.org/photos/<id>"
const response = await fetch('https://api.example.org/photos/<id>', {
method: 'GET',
});
const answer = await response.json();
import requests
response = requests.get(
"https://api.example.org/photos/<id>",
)
answer = response.json()
Answer · 200
{
"access": "string",
"alias": "string",
"allow_download": false,
"author": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"authorized": {
"add_follower": false,
"administration": false,
"audiences": [
"string"
],
"block_from_owner": false,
"comment": false,
"composers": [
"string"
],
"delete": false,
"download": false,
"edit": false,
"hide": false,
"invite": false,
"like": false,
"pin": false,
"quote": false
},
"citation_count": 1,
"comment_count": 1,
"comment_status": false,
"content": "string",
"cover_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"created_at": "2026-10-27T09:30:00Z",
"deleted": false,
"draft": false,
"editor": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"enabled": false,
"files": [
{
"alt_text": "string",
"height": 1,
"id": "string",
"position": 1,
"urls": {
"key": null
},
"width": 1
}
],
"hidden": false,
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"is_subscribed_by_viewer": false,
"language": "en",
"library_only": false,
"likes_count": 1,
"link_preview": {
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
},
"link_previews": [
{
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
}
],
"media_removed": {
"alts": [
"string"
],
"count": 1,
"gone": false
},
"mimetype": "string",
"origin_domain": "string",
"owner": {
"alias": "string",
"avatar_urls": {
"key": null
},
"body": "string",
"id": 42,
"is_following_viewer": false,
"is_leading_viewer": false,
"name": "string",
"type": "string"
},
"parent_id": 42,
"pinned": false,
"portrait_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"quote": {
"post": {
"access": null,
"alias": null,
"author": null,
"authorized": null,
"body": null,
"content": null,
"cover_urls": null,
"created_at": null,
"files": null,
"id": null,
"is_liked_by_viewer": null,
"is_reposted_by_viewer": null,
"is_saved_by_viewer": null,
"link_preview": null,
"name": null,
"owner": null,
"portrait_urls": null,
"title": null,
"type": null,
"video": null
},
"state": "string"
},
"quote_count": 1,
"quote_id": 42,
"quote_policy": "string",
"reply_access": "string",
"repost_count": 1,
"root": {
"access": "string",
"alias": "string",
"author": {
"alias": null,
"avatar_urls": null,
"id": null,
"name": null,
"type": null
},
"authorized": {
"add_follower": null,
"administration": null,
"audiences": null,
"block_from_owner": null,
"comment": null,
"composers": null,
"delete": null,
"download": null,
"edit": null,
"hide": null,
"invite": null,
"like": null,
"pin": null,
"quote": null
},
"body": "string",
"content": "string",
"cover_urls": {
"key": null
},
"created_at": "2026-10-27T09:30:00Z",
"files": [
null
],
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"link_preview": {
"description": null,
"image": null,
"site_name": null,
"title": null,
"url": null
},
"name": "string",
"owner": {
"alias": null,
"avatar_urls": null,
"body": null,
"id": null,
"is_following_viewer": null,
"is_leading_viewer": null,
"name": null,
"type": null
},
"portrait_urls": {
"key": null
},
"title": "string",
"type": "string",
"video": {
"duration": null,
"files": null,
"height": null,
"loop": null,
"poster": null,
"width": null
}
},
"root_id": 42,
"title": "string",
"type": "string",
"updated_at": "2026-10-27T09:30:00Z",
"uri": "https://example.org/",
"video": {
"duration": 1.5,
"files": [
null
],
"height": 1,
"loop": false,
"poster": "string",
"width": 1
},
"view_count": 1
}
Change a photo post's words
/photos/{id}Its title and words, both optional. Its pictures are changed with PATCH /photos/{id}/files.
Who: Somebody signed in, with media:write
Parameters
idintegerrequiredin pathThe post's id.
Body application/x-www-form-urlencoded or multipart/form-data
contentstringIts words, as Markdown, if it has any. At most 8000 characters.languagestringThe language it is written in, as a BCP 47 tag. At most 12 characters.titlestringIts title, if it has one. At most 100 characters.
Answers
- 200OKMediumNode application/json
- 400the request is not well formed, or a value in it is not one it may be
- 401no token, or one that has expired
- 403the viewer may not change it
- 404there is no such post
Request
curl -X PATCH "https://api.example.org/photos/<id>" \
-H "Authorization: Bearer $TOKEN" \
--data-urlencode "content=string" \
--data-urlencode "language=en" \
--data-urlencode "title=string"
const form = new URLSearchParams();
form.append('content', "string");
form.append('language', "en");
form.append('title', "string");
const response = await fetch('https://api.example.org/photos/<id>', {
method: 'PATCH',
headers: { Authorization: `Bearer ${token}` },
body: form,
});
const answer = await response.json();
import requests
response = requests.patch(
"https://api.example.org/photos/<id>",
headers={"Authorization": f"Bearer {token}"},
data={"content": "string", "language": "en", "title": "string"},
)
answer = response.json()
Answer · 200
{
"access": "string",
"alias": "string",
"allow_download": false,
"author": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"authorized": {
"add_follower": false,
"administration": false,
"audiences": [
"string"
],
"block_from_owner": false,
"comment": false,
"composers": [
"string"
],
"delete": false,
"download": false,
"edit": false,
"hide": false,
"invite": false,
"like": false,
"pin": false,
"quote": false
},
"citation_count": 1,
"comment_count": 1,
"comment_status": false,
"content": "string",
"cover_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"created_at": "2026-10-27T09:30:00Z",
"deleted": false,
"draft": false,
"editor": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"enabled": false,
"files": [
{
"alt_text": "string",
"height": 1,
"id": "string",
"position": 1,
"urls": {
"key": null
},
"width": 1
}
],
"hidden": false,
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"is_subscribed_by_viewer": false,
"language": "en",
"library_only": false,
"likes_count": 1,
"link_preview": {
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
},
"link_previews": [
{
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
}
],
"media_removed": {
"alts": [
"string"
],
"count": 1,
"gone": false
},
"mimetype": "string",
"origin_domain": "string",
"owner": {
"alias": "string",
"avatar_urls": {
"key": null
},
"body": "string",
"id": 42,
"is_following_viewer": false,
"is_leading_viewer": false,
"name": "string",
"type": "string"
},
"parent_id": 42,
"pinned": false,
"portrait_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"quote": {
"post": {
"access": null,
"alias": null,
"author": null,
"authorized": null,
"body": null,
"content": null,
"cover_urls": null,
"created_at": null,
"files": null,
"id": null,
"is_liked_by_viewer": null,
"is_reposted_by_viewer": null,
"is_saved_by_viewer": null,
"link_preview": null,
"name": null,
"owner": null,
"portrait_urls": null,
"title": null,
"type": null,
"video": null
},
"state": "string"
},
"quote_count": 1,
"quote_id": 42,
"quote_policy": "string",
"reply_access": "string",
"repost_count": 1,
"root": {
"access": "string",
"alias": "string",
"author": {
"alias": null,
"avatar_urls": null,
"id": null,
"name": null,
"type": null
},
"authorized": {
"add_follower": null,
"administration": null,
"audiences": null,
"block_from_owner": null,
"comment": null,
"composers": null,
"delete": null,
"download": null,
"edit": null,
"hide": null,
"invite": null,
"like": null,
"pin": null,
"quote": null
},
"body": "string",
"content": "string",
"cover_urls": {
"key": null
},
"created_at": "2026-10-27T09:30:00Z",
"files": [
null
],
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"link_preview": {
"description": null,
"image": null,
"site_name": null,
"title": null,
"url": null
},
"name": "string",
"owner": {
"alias": null,
"avatar_urls": null,
"body": null,
"id": null,
"is_following_viewer": null,
"is_leading_viewer": null,
"name": null,
"type": null
},
"portrait_urls": {
"key": null
},
"title": "string",
"type": "string",
"video": {
"duration": null,
"files": null,
"height": null,
"loop": null,
"poster": null,
"width": null
}
},
"root_id": 42,
"title": "string",
"type": "string",
"updated_at": "2026-10-27T09:30:00Z",
"uri": "https://example.org/",
"video": {
"duration": 1.5,
"files": [
null
],
"height": 1,
"loop": false,
"poster": "string",
"width": 1
},
"view_count": 1
}
Delete a photo post
/photos/{id}Who: Somebody signed in, with media:write
Parameters
idintegerrequiredin pathThe post's id.
Answers
- 200it is gone
- 400the request is not well formed, or a value in it is not one it may be
- 401no token, or one that has expired
- 403the viewer may not delete it
- 404there is no such post
Request
curl -X DELETE "https://api.example.org/photos/<id>" \
-H "Authorization: Bearer $TOKEN"
const response = await fetch('https://api.example.org/photos/<id>', {
method: 'DELETE',
headers: { Authorization: `Bearer ${token}` },
});
const answer = await response.json();
import requests
response = requests.delete(
"https://api.example.org/photos/<id>",
headers={"Authorization": f"Bearer {token}"},
)
answer = response.json()
Change who may see it
/photos/{id}/accessWho: Somebody signed in, with media:write
Parameters
idintegerrequiredin pathThe post's id.
Body application/x-www-form-urlencoded or multipart/form-data
accessstringWho may see it:public,registered,followers,leaders,mutuals,adminsormyself(permissions.md). The widest an installation allows when left out. One ofpublic,registered,followers,leaders,mutuals,admins,myself.publicunless given.
Answers
- 200OKMediumNode application/json
- 400the request is not well formed, or a value in it is not one it may be
- 401no token, or one that has expired
- 403the viewer may not change it, or it may not be shown to them
- 404there is no such post
- 422
reply_follows_its_thread: a reply has no setting of its own; its thread decidesRefusal application/json
Request
curl -X PATCH "https://api.example.org/photos/<id>/access" \
-H "Authorization: Bearer $TOKEN" \
--data-urlencode "access=public"
const form = new URLSearchParams();
form.append('access', "public");
const response = await fetch('https://api.example.org/photos/<id>/access', {
method: 'PATCH',
headers: { Authorization: `Bearer ${token}` },
body: form,
});
const answer = await response.json();
import requests
response = requests.patch(
"https://api.example.org/photos/<id>/access",
headers={"Authorization": f"Bearer {token}"},
data={"access": "public"},
)
answer = response.json()
Answer · 200
{
"access": "string",
"alias": "string",
"allow_download": false,
"author": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"authorized": {
"add_follower": false,
"administration": false,
"audiences": [
"string"
],
"block_from_owner": false,
"comment": false,
"composers": [
"string"
],
"delete": false,
"download": false,
"edit": false,
"hide": false,
"invite": false,
"like": false,
"pin": false,
"quote": false
},
"citation_count": 1,
"comment_count": 1,
"comment_status": false,
"content": "string",
"cover_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"created_at": "2026-10-27T09:30:00Z",
"deleted": false,
"draft": false,
"editor": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"enabled": false,
"files": [
{
"alt_text": "string",
"height": 1,
"id": "string",
"position": 1,
"urls": {
"key": null
},
"width": 1
}
],
"hidden": false,
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"is_subscribed_by_viewer": false,
"language": "en",
"library_only": false,
"likes_count": 1,
"link_preview": {
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
},
"link_previews": [
{
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
}
],
"media_removed": {
"alts": [
"string"
],
"count": 1,
"gone": false
},
"mimetype": "string",
"origin_domain": "string",
"owner": {
"alias": "string",
"avatar_urls": {
"key": null
},
"body": "string",
"id": 42,
"is_following_viewer": false,
"is_leading_viewer": false,
"name": "string",
"type": "string"
},
"parent_id": 42,
"pinned": false,
"portrait_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"quote": {
"post": {
"access": null,
"alias": null,
"author": null,
"authorized": null,
"body": null,
"content": null,
"cover_urls": null,
"created_at": null,
"files": null,
"id": null,
"is_liked_by_viewer": null,
"is_reposted_by_viewer": null,
"is_saved_by_viewer": null,
"link_preview": null,
"name": null,
"owner": null,
"portrait_urls": null,
"title": null,
"type": null,
"video": null
},
"state": "string"
},
"quote_count": 1,
"quote_id": 42,
"quote_policy": "string",
"reply_access": "string",
"repost_count": 1,
"root": {
"access": "string",
"alias": "string",
"author": {
"alias": null,
"avatar_urls": null,
"id": null,
"name": null,
"type": null
},
"authorized": {
"add_follower": null,
"administration": null,
"audiences": null,
"block_from_owner": null,
"comment": null,
"composers": null,
"delete": null,
"download": null,
"edit": null,
"hide": null,
"invite": null,
"like": null,
"pin": null,
"quote": null
},
"body": "string",
"content": "string",
"cover_urls": {
"key": null
},
"created_at": "2026-10-27T09:30:00Z",
"files": [
null
],
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"link_preview": {
"description": null,
"image": null,
"site_name": null,
"title": null,
"url": null
},
"name": "string",
"owner": {
"alias": null,
"avatar_urls": null,
"body": null,
"id": null,
"is_following_viewer": null,
"is_leading_viewer": null,
"name": null,
"type": null
},
"portrait_urls": {
"key": null
},
"title": "string",
"type": "string",
"video": {
"duration": null,
"files": null,
"height": null,
"loop": null,
"poster": null,
"width": null
}
},
"root_id": 42,
"title": "string",
"type": "string",
"updated_at": "2026-10-27T09:30:00Z",
"uri": "https://example.org/",
"video": {
"duration": 1.5,
"files": [
null
],
"height": 1,
"loop": false,
"poster": "string",
"width": 1
},
"view_count": 1
}
Open or close replies
/photos/{id}/comment-statusWho: Somebody signed in, with media:write
Parameters
idintegerrequiredin pathThe post's id.
Body application/x-www-form-urlencoded or multipart/form-data
statusbooleanWhether it takes replies.
Answers
- 200OKMediumNode application/json
- 400the request is not well formed, or a value in it is not one it may be
- 401no token, or one that has expired
- 403the viewer may not change it
- 404there is no such post
- 422
reply_follows_its_thread: a reply has no setting of its own; its thread decidesRefusal application/json
Request
curl -X PATCH "https://api.example.org/photos/<id>/comment-status" \
-H "Authorization: Bearer $TOKEN" \
--data-urlencode "status=false"
const form = new URLSearchParams();
form.append('status', "false");
const response = await fetch('https://api.example.org/photos/<id>/comment-status', {
method: 'PATCH',
headers: { Authorization: `Bearer ${token}` },
body: form,
});
const answer = await response.json();
import requests
response = requests.patch(
"https://api.example.org/photos/<id>/comment-status",
headers={"Authorization": f"Bearer {token}"},
data={"status": "false"},
)
answer = response.json()
Answer · 200
{
"access": "string",
"alias": "string",
"allow_download": false,
"author": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"authorized": {
"add_follower": false,
"administration": false,
"audiences": [
"string"
],
"block_from_owner": false,
"comment": false,
"composers": [
"string"
],
"delete": false,
"download": false,
"edit": false,
"hide": false,
"invite": false,
"like": false,
"pin": false,
"quote": false
},
"citation_count": 1,
"comment_count": 1,
"comment_status": false,
"content": "string",
"cover_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"created_at": "2026-10-27T09:30:00Z",
"deleted": false,
"draft": false,
"editor": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"enabled": false,
"files": [
{
"alt_text": "string",
"height": 1,
"id": "string",
"position": 1,
"urls": {
"key": null
},
"width": 1
}
],
"hidden": false,
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"is_subscribed_by_viewer": false,
"language": "en",
"library_only": false,
"likes_count": 1,
"link_preview": {
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
},
"link_previews": [
{
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
}
],
"media_removed": {
"alts": [
"string"
],
"count": 1,
"gone": false
},
"mimetype": "string",
"origin_domain": "string",
"owner": {
"alias": "string",
"avatar_urls": {
"key": null
},
"body": "string",
"id": 42,
"is_following_viewer": false,
"is_leading_viewer": false,
"name": "string",
"type": "string"
},
"parent_id": 42,
"pinned": false,
"portrait_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"quote": {
"post": {
"access": null,
"alias": null,
"author": null,
"authorized": null,
"body": null,
"content": null,
"cover_urls": null,
"created_at": null,
"files": null,
"id": null,
"is_liked_by_viewer": null,
"is_reposted_by_viewer": null,
"is_saved_by_viewer": null,
"link_preview": null,
"name": null,
"owner": null,
"portrait_urls": null,
"title": null,
"type": null,
"video": null
},
"state": "string"
},
"quote_count": 1,
"quote_id": 42,
"quote_policy": "string",
"reply_access": "string",
"repost_count": 1,
"root": {
"access": "string",
"alias": "string",
"author": {
"alias": null,
"avatar_urls": null,
"id": null,
"name": null,
"type": null
},
"authorized": {
"add_follower": null,
"administration": null,
"audiences": null,
"block_from_owner": null,
"comment": null,
"composers": null,
"delete": null,
"download": null,
"edit": null,
"hide": null,
"invite": null,
"like": null,
"pin": null,
"quote": null
},
"body": "string",
"content": "string",
"cover_urls": {
"key": null
},
"created_at": "2026-10-27T09:30:00Z",
"files": [
null
],
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"link_preview": {
"description": null,
"image": null,
"site_name": null,
"title": null,
"url": null
},
"name": "string",
"owner": {
"alias": null,
"avatar_urls": null,
"body": null,
"id": null,
"is_following_viewer": null,
"is_leading_viewer": null,
"name": null,
"type": null
},
"portrait_urls": {
"key": null
},
"title": "string",
"type": "string",
"video": {
"duration": null,
"files": null,
"height": null,
"loop": null,
"poster": null,
"width": null
}
},
"root_id": 42,
"title": "string",
"type": "string",
"updated_at": "2026-10-27T09:30:00Z",
"uri": "https://example.org/",
"video": {
"duration": 1.5,
"files": [
null
],
"height": 1,
"loop": false,
"poster": "string",
"width": 1
},
"view_count": 1
}
Download an image
/photos/{id}/downloadA redirect to the largest copy there is, named to be saved. For whoever may see the post, when it may be downloaded.
Who: Anyone, signed in or not
Parameters
idintegerrequiredin pathThe post's id.fileintegerin queryWhich of its images, from 0. The first when left out.
Answers
- 302the file is at the address in Location
- 403it may not be downloaded
- 404there is no such post or image that the viewer may see
- 429too many downloads lately
Request
curl "https://api.example.org/photos/<id>/download"
const response = await fetch('https://api.example.org/photos/<id>/download', {
method: 'GET',
});
const answer = await response.json();
import requests
response = requests.get(
"https://api.example.org/photos/<id>/download",
)
answer = response.json()
Change whether it may be downloaded
/photos/{id}/downloadWho: Somebody signed in, with media:write
Parameters
idintegerrequiredin pathThe post's id.
Body application/json or application/x-www-form-urlencoded or multipart/form-data
allowbooleanWhether whoever can see it may download it.
Answers
- 200OKMediumNode application/json
- 400the request is not well formed, or a value in it is not one it may be
- 401no token, or one that has expired
- 403the viewer may not change it
- 404there is no such post
Request
curl -X PATCH "https://api.example.org/photos/<id>/download" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"allow": false
}'
const response = await fetch('https://api.example.org/photos/<id>/download', {
method: 'PATCH',
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
"allow": false
}),
});
const answer = await response.json();
import requests
response = requests.patch(
"https://api.example.org/photos/<id>/download",
headers={"Authorization": f"Bearer {token}"},
json={
"allow": False
},
)
answer = response.json()
Answer · 200
{
"access": "string",
"alias": "string",
"allow_download": false,
"author": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"authorized": {
"add_follower": false,
"administration": false,
"audiences": [
"string"
],
"block_from_owner": false,
"comment": false,
"composers": [
"string"
],
"delete": false,
"download": false,
"edit": false,
"hide": false,
"invite": false,
"like": false,
"pin": false,
"quote": false
},
"citation_count": 1,
"comment_count": 1,
"comment_status": false,
"content": "string",
"cover_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"created_at": "2026-10-27T09:30:00Z",
"deleted": false,
"draft": false,
"editor": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"enabled": false,
"files": [
{
"alt_text": "string",
"height": 1,
"id": "string",
"position": 1,
"urls": {
"key": null
},
"width": 1
}
],
"hidden": false,
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"is_subscribed_by_viewer": false,
"language": "en",
"library_only": false,
"likes_count": 1,
"link_preview": {
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
},
"link_previews": [
{
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
}
],
"media_removed": {
"alts": [
"string"
],
"count": 1,
"gone": false
},
"mimetype": "string",
"origin_domain": "string",
"owner": {
"alias": "string",
"avatar_urls": {
"key": null
},
"body": "string",
"id": 42,
"is_following_viewer": false,
"is_leading_viewer": false,
"name": "string",
"type": "string"
},
"parent_id": 42,
"pinned": false,
"portrait_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"quote": {
"post": {
"access": null,
"alias": null,
"author": null,
"authorized": null,
"body": null,
"content": null,
"cover_urls": null,
"created_at": null,
"files": null,
"id": null,
"is_liked_by_viewer": null,
"is_reposted_by_viewer": null,
"is_saved_by_viewer": null,
"link_preview": null,
"name": null,
"owner": null,
"portrait_urls": null,
"title": null,
"type": null,
"video": null
},
"state": "string"
},
"quote_count": 1,
"quote_id": 42,
"quote_policy": "string",
"reply_access": "string",
"repost_count": 1,
"root": {
"access": "string",
"alias": "string",
"author": {
"alias": null,
"avatar_urls": null,
"id": null,
"name": null,
"type": null
},
"authorized": {
"add_follower": null,
"administration": null,
"audiences": null,
"block_from_owner": null,
"comment": null,
"composers": null,
"delete": null,
"download": null,
"edit": null,
"hide": null,
"invite": null,
"like": null,
"pin": null,
"quote": null
},
"body": "string",
"content": "string",
"cover_urls": {
"key": null
},
"created_at": "2026-10-27T09:30:00Z",
"files": [
null
],
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"link_preview": {
"description": null,
"image": null,
"site_name": null,
"title": null,
"url": null
},
"name": "string",
"owner": {
"alias": null,
"avatar_urls": null,
"body": null,
"id": null,
"is_following_viewer": null,
"is_leading_viewer": null,
"name": null,
"type": null
},
"portrait_urls": {
"key": null
},
"title": "string",
"type": "string",
"video": {
"duration": null,
"files": null,
"height": null,
"loop": null,
"poster": null,
"width": null
}
},
"root_id": 42,
"title": "string",
"type": "string",
"updated_at": "2026-10-27T09:30:00Z",
"uri": "https://example.org/",
"video": {
"duration": 1.5,
"files": [
null
],
"height": 1,
"loop": false,
"poster": "string",
"width": 1
},
"view_count": 1
}
Change a post's images
/photos/{id}/filesThe whole list as it is to be: their order, what each shows, and which there are. One left out is removed; one named by an upload is added.
Who: Somebody signed in, with media:write
Parameters
idintegerrequiredin pathThe post's id.
Body application/json
fileslist of photo.FileRefEvery image it is to have, in order. One left out is removed.
Answers
- 200OKMediumNode application/json
- 400the request is not well formed, or a value in it is not one it may be
- 401no token, or one that has expired
- 403the viewer may not change it, or the images were refused; the answer says why
- 404there is no such post, or the images were refused; the answer says why
- 422Unprocessable Entityphoto.FilesRefusal application/json
Request
curl -X PATCH "https://api.example.org/photos/<id>/files" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"files": [
{
"alt_text": "string",
"id": "string",
"upload_id": 42
}
]
}'
const response = await fetch('https://api.example.org/photos/<id>/files', {
method: 'PATCH',
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
"files": [
{
"alt_text": "string",
"id": "string",
"upload_id": 42
}
]
}),
});
const answer = await response.json();
import requests
response = requests.patch(
"https://api.example.org/photos/<id>/files",
headers={"Authorization": f"Bearer {token}"},
json={
"files": [
{
"alt_text": "string",
"id": "string",
"upload_id": 42
}
]
},
)
answer = response.json()
Answer · 200
{
"access": "string",
"alias": "string",
"allow_download": false,
"author": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"authorized": {
"add_follower": false,
"administration": false,
"audiences": [
"string"
],
"block_from_owner": false,
"comment": false,
"composers": [
"string"
],
"delete": false,
"download": false,
"edit": false,
"hide": false,
"invite": false,
"like": false,
"pin": false,
"quote": false
},
"citation_count": 1,
"comment_count": 1,
"comment_status": false,
"content": "string",
"cover_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"created_at": "2026-10-27T09:30:00Z",
"deleted": false,
"draft": false,
"editor": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"enabled": false,
"files": [
{
"alt_text": "string",
"height": 1,
"id": "string",
"position": 1,
"urls": {
"key": null
},
"width": 1
}
],
"hidden": false,
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"is_subscribed_by_viewer": false,
"language": "en",
"library_only": false,
"likes_count": 1,
"link_preview": {
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
},
"link_previews": [
{
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
}
],
"media_removed": {
"alts": [
"string"
],
"count": 1,
"gone": false
},
"mimetype": "string",
"origin_domain": "string",
"owner": {
"alias": "string",
"avatar_urls": {
"key": null
},
"body": "string",
"id": 42,
"is_following_viewer": false,
"is_leading_viewer": false,
"name": "string",
"type": "string"
},
"parent_id": 42,
"pinned": false,
"portrait_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"quote": {
"post": {
"access": null,
"alias": null,
"author": null,
"authorized": null,
"body": null,
"content": null,
"cover_urls": null,
"created_at": null,
"files": null,
"id": null,
"is_liked_by_viewer": null,
"is_reposted_by_viewer": null,
"is_saved_by_viewer": null,
"link_preview": null,
"name": null,
"owner": null,
"portrait_urls": null,
"title": null,
"type": null,
"video": null
},
"state": "string"
},
"quote_count": 1,
"quote_id": 42,
"quote_policy": "string",
"reply_access": "string",
"repost_count": 1,
"root": {
"access": "string",
"alias": "string",
"author": {
"alias": null,
"avatar_urls": null,
"id": null,
"name": null,
"type": null
},
"authorized": {
"add_follower": null,
"administration": null,
"audiences": null,
"block_from_owner": null,
"comment": null,
"composers": null,
"delete": null,
"download": null,
"edit": null,
"hide": null,
"invite": null,
"like": null,
"pin": null,
"quote": null
},
"body": "string",
"content": "string",
"cover_urls": {
"key": null
},
"created_at": "2026-10-27T09:30:00Z",
"files": [
null
],
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"link_preview": {
"description": null,
"image": null,
"site_name": null,
"title": null,
"url": null
},
"name": "string",
"owner": {
"alias": null,
"avatar_urls": null,
"body": null,
"id": null,
"is_following_viewer": null,
"is_leading_viewer": null,
"name": null,
"type": null
},
"portrait_urls": {
"key": null
},
"title": "string",
"type": "string",
"video": {
"duration": null,
"files": null,
"height": null,
"loop": null,
"poster": null,
"width": null
}
},
"root_id": 42,
"title": "string",
"type": "string",
"updated_at": "2026-10-27T09:30:00Z",
"uri": "https://example.org/",
"video": {
"duration": 1.5,
"files": [
null
],
"height": 1,
"loop": false,
"poster": "string",
"width": 1
},
"view_count": 1
}
Pin it to the profile it is on
/photos/{id}/pinA profile has one pin: pinning another post moves it. For the profile and its administrators, and site administrators (permissions.md). Answers with the post.
Who: Somebody signed in, with media:write
Parameters
idintegerrequiredin pathThe post's id.
Answers
- 200OKMediumNode application/json
- 400the request is not well formed, or a value in it is not one it may be
- 401no token, or one that has expired
- 403the viewer may not pin it
- 404there is no such post
- 422
reply_cannot_be_pinnedRefusal application/json
Request
curl -X PUT "https://api.example.org/photos/<id>/pin" \
-H "Authorization: Bearer $TOKEN"
const response = await fetch('https://api.example.org/photos/<id>/pin', {
method: 'PUT',
headers: { Authorization: `Bearer ${token}` },
});
const answer = await response.json();
import requests
response = requests.put(
"https://api.example.org/photos/<id>/pin",
headers={"Authorization": f"Bearer {token}"},
)
answer = response.json()
Answer · 200
{
"access": "string",
"alias": "string",
"allow_download": false,
"author": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"authorized": {
"add_follower": false,
"administration": false,
"audiences": [
"string"
],
"block_from_owner": false,
"comment": false,
"composers": [
"string"
],
"delete": false,
"download": false,
"edit": false,
"hide": false,
"invite": false,
"like": false,
"pin": false,
"quote": false
},
"citation_count": 1,
"comment_count": 1,
"comment_status": false,
"content": "string",
"cover_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"created_at": "2026-10-27T09:30:00Z",
"deleted": false,
"draft": false,
"editor": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"enabled": false,
"files": [
{
"alt_text": "string",
"height": 1,
"id": "string",
"position": 1,
"urls": {
"key": null
},
"width": 1
}
],
"hidden": false,
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"is_subscribed_by_viewer": false,
"language": "en",
"library_only": false,
"likes_count": 1,
"link_preview": {
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
},
"link_previews": [
{
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
}
],
"media_removed": {
"alts": [
"string"
],
"count": 1,
"gone": false
},
"mimetype": "string",
"origin_domain": "string",
"owner": {
"alias": "string",
"avatar_urls": {
"key": null
},
"body": "string",
"id": 42,
"is_following_viewer": false,
"is_leading_viewer": false,
"name": "string",
"type": "string"
},
"parent_id": 42,
"pinned": false,
"portrait_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"quote": {
"post": {
"access": null,
"alias": null,
"author": null,
"authorized": null,
"body": null,
"content": null,
"cover_urls": null,
"created_at": null,
"files": null,
"id": null,
"is_liked_by_viewer": null,
"is_reposted_by_viewer": null,
"is_saved_by_viewer": null,
"link_preview": null,
"name": null,
"owner": null,
"portrait_urls": null,
"title": null,
"type": null,
"video": null
},
"state": "string"
},
"quote_count": 1,
"quote_id": 42,
"quote_policy": "string",
"reply_access": "string",
"repost_count": 1,
"root": {
"access": "string",
"alias": "string",
"author": {
"alias": null,
"avatar_urls": null,
"id": null,
"name": null,
"type": null
},
"authorized": {
"add_follower": null,
"administration": null,
"audiences": null,
"block_from_owner": null,
"comment": null,
"composers": null,
"delete": null,
"download": null,
"edit": null,
"hide": null,
"invite": null,
"like": null,
"pin": null,
"quote": null
},
"body": "string",
"content": "string",
"cover_urls": {
"key": null
},
"created_at": "2026-10-27T09:30:00Z",
"files": [
null
],
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"link_preview": {
"description": null,
"image": null,
"site_name": null,
"title": null,
"url": null
},
"name": "string",
"owner": {
"alias": null,
"avatar_urls": null,
"body": null,
"id": null,
"is_following_viewer": null,
"is_leading_viewer": null,
"name": null,
"type": null
},
"portrait_urls": {
"key": null
},
"title": "string",
"type": "string",
"video": {
"duration": null,
"files": null,
"height": null,
"loop": null,
"poster": null,
"width": null
}
},
"root_id": 42,
"title": "string",
"type": "string",
"updated_at": "2026-10-27T09:30:00Z",
"uri": "https://example.org/",
"video": {
"duration": 1.5,
"files": [
null
],
"height": 1,
"loop": false,
"poster": "string",
"width": 1
},
"view_count": 1
}
Take its pin off
/photos/{id}/pinA profile has one pin: pinning another post moves it. For the profile and its administrators, and site administrators (permissions.md). Answers with the post.
Who: Somebody signed in, with media:write
Parameters
idintegerrequiredin pathThe post's id.
Answers
- 200OKMediumNode application/json
- 400the request is not well formed, or a value in it is not one it may be
- 401no token, or one that has expired
- 403the viewer may not pin it
- 404there is no such post
- 422
reply_cannot_be_pinnedRefusal application/json
Request
curl -X DELETE "https://api.example.org/photos/<id>/pin" \
-H "Authorization: Bearer $TOKEN"
const response = await fetch('https://api.example.org/photos/<id>/pin', {
method: 'DELETE',
headers: { Authorization: `Bearer ${token}` },
});
const answer = await response.json();
import requests
response = requests.delete(
"https://api.example.org/photos/<id>/pin",
headers={"Authorization": f"Bearer {token}"},
)
answer = response.json()
Answer · 200
{
"access": "string",
"alias": "string",
"allow_download": false,
"author": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"authorized": {
"add_follower": false,
"administration": false,
"audiences": [
"string"
],
"block_from_owner": false,
"comment": false,
"composers": [
"string"
],
"delete": false,
"download": false,
"edit": false,
"hide": false,
"invite": false,
"like": false,
"pin": false,
"quote": false
},
"citation_count": 1,
"comment_count": 1,
"comment_status": false,
"content": "string",
"cover_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"created_at": "2026-10-27T09:30:00Z",
"deleted": false,
"draft": false,
"editor": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"enabled": false,
"files": [
{
"alt_text": "string",
"height": 1,
"id": "string",
"position": 1,
"urls": {
"key": null
},
"width": 1
}
],
"hidden": false,
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"is_subscribed_by_viewer": false,
"language": "en",
"library_only": false,
"likes_count": 1,
"link_preview": {
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
},
"link_previews": [
{
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
}
],
"media_removed": {
"alts": [
"string"
],
"count": 1,
"gone": false
},
"mimetype": "string",
"origin_domain": "string",
"owner": {
"alias": "string",
"avatar_urls": {
"key": null
},
"body": "string",
"id": 42,
"is_following_viewer": false,
"is_leading_viewer": false,
"name": "string",
"type": "string"
},
"parent_id": 42,
"pinned": false,
"portrait_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"quote": {
"post": {
"access": null,
"alias": null,
"author": null,
"authorized": null,
"body": null,
"content": null,
"cover_urls": null,
"created_at": null,
"files": null,
"id": null,
"is_liked_by_viewer": null,
"is_reposted_by_viewer": null,
"is_saved_by_viewer": null,
"link_preview": null,
"name": null,
"owner": null,
"portrait_urls": null,
"title": null,
"type": null,
"video": null
},
"state": "string"
},
"quote_count": 1,
"quote_id": 42,
"quote_policy": "string",
"reply_access": "string",
"repost_count": 1,
"root": {
"access": "string",
"alias": "string",
"author": {
"alias": null,
"avatar_urls": null,
"id": null,
"name": null,
"type": null
},
"authorized": {
"add_follower": null,
"administration": null,
"audiences": null,
"block_from_owner": null,
"comment": null,
"composers": null,
"delete": null,
"download": null,
"edit": null,
"hide": null,
"invite": null,
"like": null,
"pin": null,
"quote": null
},
"body": "string",
"content": "string",
"cover_urls": {
"key": null
},
"created_at": "2026-10-27T09:30:00Z",
"files": [
null
],
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"link_preview": {
"description": null,
"image": null,
"site_name": null,
"title": null,
"url": null
},
"name": "string",
"owner": {
"alias": null,
"avatar_urls": null,
"body": null,
"id": null,
"is_following_viewer": null,
"is_leading_viewer": null,
"name": null,
"type": null
},
"portrait_urls": {
"key": null
},
"title": "string",
"type": "string",
"video": {
"duration": null,
"files": null,
"height": null,
"loop": null,
"poster": null,
"width": null
}
},
"root_id": 42,
"title": "string",
"type": "string",
"updated_at": "2026-10-27T09:30:00Z",
"uri": "https://example.org/",
"video": {
"duration": 1.5,
"files": [
null
],
"height": 1,
"loop": false,
"poster": "string",
"width": 1
},
"view_count": 1
}
Change who may quote it
/photos/{id}/quote-policyWho: Somebody signed in, with media:write
Parameters
idintegerrequiredin pathThe post's id.
Body application/json or application/x-www-form-urlencoded or multipart/form-data
quote_policystringrequiredWho may quote it:anyone,followersornobody. At most 16 characters.
Answers
- 200OKMediumNode application/json
- 400
quote_policy_invalid, or not well formedRefusal application/json - 401no token, or one that has expired
- 403the viewer may not change it
- 404there is no such post
- 422
reply_follows_its_thread: a reply has no setting of its own; its thread decidesRefusal application/json
Request
curl -X PATCH "https://api.example.org/photos/<id>/quote-policy" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"quote_policy": "string"
}'
const response = await fetch('https://api.example.org/photos/<id>/quote-policy', {
method: 'PATCH',
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
"quote_policy": "string"
}),
});
const answer = await response.json();
import requests
response = requests.patch(
"https://api.example.org/photos/<id>/quote-policy",
headers={"Authorization": f"Bearer {token}"},
json={
"quote_policy": "string"
},
)
answer = response.json()
Answer · 200
{
"access": "string",
"alias": "string",
"allow_download": false,
"author": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"authorized": {
"add_follower": false,
"administration": false,
"audiences": [
"string"
],
"block_from_owner": false,
"comment": false,
"composers": [
"string"
],
"delete": false,
"download": false,
"edit": false,
"hide": false,
"invite": false,
"like": false,
"pin": false,
"quote": false
},
"citation_count": 1,
"comment_count": 1,
"comment_status": false,
"content": "string",
"cover_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"created_at": "2026-10-27T09:30:00Z",
"deleted": false,
"draft": false,
"editor": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"enabled": false,
"files": [
{
"alt_text": "string",
"height": 1,
"id": "string",
"position": 1,
"urls": {
"key": null
},
"width": 1
}
],
"hidden": false,
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"is_subscribed_by_viewer": false,
"language": "en",
"library_only": false,
"likes_count": 1,
"link_preview": {
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
},
"link_previews": [
{
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
}
],
"media_removed": {
"alts": [
"string"
],
"count": 1,
"gone": false
},
"mimetype": "string",
"origin_domain": "string",
"owner": {
"alias": "string",
"avatar_urls": {
"key": null
},
"body": "string",
"id": 42,
"is_following_viewer": false,
"is_leading_viewer": false,
"name": "string",
"type": "string"
},
"parent_id": 42,
"pinned": false,
"portrait_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"quote": {
"post": {
"access": null,
"alias": null,
"author": null,
"authorized": null,
"body": null,
"content": null,
"cover_urls": null,
"created_at": null,
"files": null,
"id": null,
"is_liked_by_viewer": null,
"is_reposted_by_viewer": null,
"is_saved_by_viewer": null,
"link_preview": null,
"name": null,
"owner": null,
"portrait_urls": null,
"title": null,
"type": null,
"video": null
},
"state": "string"
},
"quote_count": 1,
"quote_id": 42,
"quote_policy": "string",
"reply_access": "string",
"repost_count": 1,
"root": {
"access": "string",
"alias": "string",
"author": {
"alias": null,
"avatar_urls": null,
"id": null,
"name": null,
"type": null
},
"authorized": {
"add_follower": null,
"administration": null,
"audiences": null,
"block_from_owner": null,
"comment": null,
"composers": null,
"delete": null,
"download": null,
"edit": null,
"hide": null,
"invite": null,
"like": null,
"pin": null,
"quote": null
},
"body": "string",
"content": "string",
"cover_urls": {
"key": null
},
"created_at": "2026-10-27T09:30:00Z",
"files": [
null
],
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"link_preview": {
"description": null,
"image": null,
"site_name": null,
"title": null,
"url": null
},
"name": "string",
"owner": {
"alias": null,
"avatar_urls": null,
"body": null,
"id": null,
"is_following_viewer": null,
"is_leading_viewer": null,
"name": null,
"type": null
},
"portrait_urls": {
"key": null
},
"title": "string",
"type": "string",
"video": {
"duration": null,
"files": null,
"height": null,
"loop": null,
"poster": null,
"width": null
}
},
"root_id": 42,
"title": "string",
"type": "string",
"updated_at": "2026-10-27T09:30:00Z",
"uri": "https://example.org/",
"video": {
"duration": 1.5,
"files": [
null
],
"height": 1,
"loop": false,
"poster": "string",
"width": 1
},
"view_count": 1
}
Reply with pictures
/photos/{id}/repliesA photo post in the thread of the post id, owned by whoever writes it, as a reply with words alone is a note. Its pictures are uploaded first, for the person replying.
Who: Somebody signed in, with media:write
Parameters
idintegerrequiredin pathThe id of the post or the reply it answers. Read by the handler from the path itself.
Body application/json
contentstringIts words, as Markdown. A reply with pictures need not have any. At most 8000 characters.languagestringThe language it is written in, as a BCP 47 tag. At most 12 characters.uploadslist of photo.FileRefIts pictures, each uploaded first for the person replying.
Body application/x-www-form-urlencoded or multipart/form-data
contentstringIts words, as Markdown. A reply with pictures need not have any. At most 8000 characters.languagestringThe language it is written in, as a BCP 47 tag. At most 12 characters.
Answers
- 201CreatedMediumNode application/json
- 400the request is not well formed, or a value in it is not one it may be
- 401no token, or one that has expired
- 403the viewer may not reply here
- 404there is no such post the viewer may see
- 410it answers a reply that was removed
Request
curl -X POST "https://api.example.org/photos/<id>/replies" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"content": "string",
"language": "en",
"uploads": [
{
"alt_text": "string",
"id": "string",
"upload_id": 42
}
]
}'
const response = await fetch('https://api.example.org/photos/<id>/replies', {
method: 'POST',
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
"content": "string",
"language": "en",
"uploads": [
{
"alt_text": "string",
"id": "string",
"upload_id": 42
}
]
}),
});
const answer = await response.json();
import requests
response = requests.post(
"https://api.example.org/photos/<id>/replies",
headers={"Authorization": f"Bearer {token}"},
json={
"content": "string",
"language": "en",
"uploads": [
{
"alt_text": "string",
"id": "string",
"upload_id": 42
}
]
},
)
answer = response.json()
Answer · 201
{
"access": "string",
"alias": "string",
"allow_download": false,
"author": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"authorized": {
"add_follower": false,
"administration": false,
"audiences": [
"string"
],
"block_from_owner": false,
"comment": false,
"composers": [
"string"
],
"delete": false,
"download": false,
"edit": false,
"hide": false,
"invite": false,
"like": false,
"pin": false,
"quote": false
},
"citation_count": 1,
"comment_count": 1,
"comment_status": false,
"content": "string",
"cover_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"created_at": "2026-10-27T09:30:00Z",
"deleted": false,
"draft": false,
"editor": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"enabled": false,
"files": [
{
"alt_text": "string",
"height": 1,
"id": "string",
"position": 1,
"urls": {
"key": null
},
"width": 1
}
],
"hidden": false,
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"is_subscribed_by_viewer": false,
"language": "en",
"library_only": false,
"likes_count": 1,
"link_preview": {
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
},
"link_previews": [
{
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
}
],
"media_removed": {
"alts": [
"string"
],
"count": 1,
"gone": false
},
"mimetype": "string",
"origin_domain": "string",
"owner": {
"alias": "string",
"avatar_urls": {
"key": null
},
"body": "string",
"id": 42,
"is_following_viewer": false,
"is_leading_viewer": false,
"name": "string",
"type": "string"
},
"parent_id": 42,
"pinned": false,
"portrait_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"quote": {
"post": {
"access": null,
"alias": null,
"author": null,
"authorized": null,
"body": null,
"content": null,
"cover_urls": null,
"created_at": null,
"files": null,
"id": null,
"is_liked_by_viewer": null,
"is_reposted_by_viewer": null,
"is_saved_by_viewer": null,
"link_preview": null,
"name": null,
"owner": null,
"portrait_urls": null,
"title": null,
"type": null,
"video": null
},
"state": "string"
},
"quote_count": 1,
"quote_id": 42,
"quote_policy": "string",
"reply_access": "string",
"repost_count": 1,
"root": {
"access": "string",
"alias": "string",
"author": {
"alias": null,
"avatar_urls": null,
"id": null,
"name": null,
"type": null
},
"authorized": {
"add_follower": null,
"administration": null,
"audiences": null,
"block_from_owner": null,
"comment": null,
"composers": null,
"delete": null,
"download": null,
"edit": null,
"hide": null,
"invite": null,
"like": null,
"pin": null,
"quote": null
},
"body": "string",
"content": "string",
"cover_urls": {
"key": null
},
"created_at": "2026-10-27T09:30:00Z",
"files": [
null
],
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"link_preview": {
"description": null,
"image": null,
"site_name": null,
"title": null,
"url": null
},
"name": "string",
"owner": {
"alias": null,
"avatar_urls": null,
"body": null,
"id": null,
"is_following_viewer": null,
"is_leading_viewer": null,
"name": null,
"type": null
},
"portrait_urls": {
"key": null
},
"title": "string",
"type": "string",
"video": {
"duration": null,
"files": null,
"height": null,
"loop": null,
"poster": null,
"width": null
}
},
"root_id": 42,
"title": "string",
"type": "string",
"updated_at": "2026-10-27T09:30:00Z",
"uri": "https://example.org/",
"video": {
"duration": 1.5,
"files": [
null
],
"height": 1,
"loop": false,
"poster": "string",
"width": 1
},
"view_count": 1
}
Change who may reply
/photos/{id}/reply-accessWho: Somebody signed in, with media:write
Parameters
idintegerrequiredin pathThe post's id.
Body application/json or application/x-www-form-urlencoded or multipart/form-data
reply_accessstringrequiredWho may reply:anyone,nobody, or any offollowers,followingandmentionedjoined by commas. At most 64 characters.
Answers
- 200OKMediumNode application/json
- 400
reply_access_invalid, or not well formedRefusal application/json - 401no token, or one that has expired
- 403the viewer may not change it
- 404there is no such post
- 422
reply_follows_its_thread: a reply has no setting of its own; its thread decidesRefusal application/json
Request
curl -X PATCH "https://api.example.org/photos/<id>/reply-access" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"reply_access": "string"
}'
const response = await fetch('https://api.example.org/photos/<id>/reply-access', {
method: 'PATCH',
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
"reply_access": "string"
}),
});
const answer = await response.json();
import requests
response = requests.patch(
"https://api.example.org/photos/<id>/reply-access",
headers={"Authorization": f"Bearer {token}"},
json={
"reply_access": "string"
},
)
answer = response.json()
Answer · 200
{
"access": "string",
"alias": "string",
"allow_download": false,
"author": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"authorized": {
"add_follower": false,
"administration": false,
"audiences": [
"string"
],
"block_from_owner": false,
"comment": false,
"composers": [
"string"
],
"delete": false,
"download": false,
"edit": false,
"hide": false,
"invite": false,
"like": false,
"pin": false,
"quote": false
},
"citation_count": 1,
"comment_count": 1,
"comment_status": false,
"content": "string",
"cover_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"created_at": "2026-10-27T09:30:00Z",
"deleted": false,
"draft": false,
"editor": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"enabled": false,
"files": [
{
"alt_text": "string",
"height": 1,
"id": "string",
"position": 1,
"urls": {
"key": null
},
"width": 1
}
],
"hidden": false,
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"is_subscribed_by_viewer": false,
"language": "en",
"library_only": false,
"likes_count": 1,
"link_preview": {
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
},
"link_previews": [
{
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
}
],
"media_removed": {
"alts": [
"string"
],
"count": 1,
"gone": false
},
"mimetype": "string",
"origin_domain": "string",
"owner": {
"alias": "string",
"avatar_urls": {
"key": null
},
"body": "string",
"id": 42,
"is_following_viewer": false,
"is_leading_viewer": false,
"name": "string",
"type": "string"
},
"parent_id": 42,
"pinned": false,
"portrait_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"quote": {
"post": {
"access": null,
"alias": null,
"author": null,
"authorized": null,
"body": null,
"content": null,
"cover_urls": null,
"created_at": null,
"files": null,
"id": null,
"is_liked_by_viewer": null,
"is_reposted_by_viewer": null,
"is_saved_by_viewer": null,
"link_preview": null,
"name": null,
"owner": null,
"portrait_urls": null,
"title": null,
"type": null,
"video": null
},
"state": "string"
},
"quote_count": 1,
"quote_id": 42,
"quote_policy": "string",
"reply_access": "string",
"repost_count": 1,
"root": {
"access": "string",
"alias": "string",
"author": {
"alias": null,
"avatar_urls": null,
"id": null,
"name": null,
"type": null
},
"authorized": {
"add_follower": null,
"administration": null,
"audiences": null,
"block_from_owner": null,
"comment": null,
"composers": null,
"delete": null,
"download": null,
"edit": null,
"hide": null,
"invite": null,
"like": null,
"pin": null,
"quote": null
},
"body": "string",
"content": "string",
"cover_urls": {
"key": null
},
"created_at": "2026-10-27T09:30:00Z",
"files": [
null
],
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"link_preview": {
"description": null,
"image": null,
"site_name": null,
"title": null,
"url": null
},
"name": "string",
"owner": {
"alias": null,
"avatar_urls": null,
"body": null,
"id": null,
"is_following_viewer": null,
"is_leading_viewer": null,
"name": null,
"type": null
},
"portrait_urls": {
"key": null
},
"title": "string",
"type": "string",
"video": {
"duration": null,
"files": null,
"height": null,
"loop": null,
"poster": null,
"width": null
}
},
"root_id": 42,
"title": "string",
"type": "string",
"updated_at": "2026-10-27T09:30:00Z",
"uri": "https://example.org/",
"video": {
"duration": 1.5,
"files": [
null
],
"height": 1,
"loop": false,
"poster": "string",
"width": 1
},
"view_count": 1
}
A profile's photo posts
/photos/{owner_id}/Those the viewer may see.
Who: Anyone, signed in or not
Parameters
startintegerin queryHow many to pass over. At least 0.limitintegerin queryThe most to send. At least 0.20unless given.orderingstringin queryWhat they are ordered by. At most 15 characters. One ofupdated_at,created_at,enabled.created_atunless given.dirstringin queryWhich way the order runs. At most 4 characters. One ofasc,desc.descunless given.disabledbooleanin queryDisabled posts as well, for whoever may see them.owner_idintegerrequiredin pathThe profile whose posts are listed. At least 1.librarybooleanin queryThe viewer's own media library instead: all their photo or video posts on their own profile, with those they put up from inside the article editor, which no other list holds. The owner is then the viewer, whatever the path says.draftsbooleanin queryThe viewer's own drafts on this profile instead, articles or topics still being written, which no other list holds.
Answers
- 200OKobject application/json
- 400the request is not well formed, or a value in it is not one it may be
Request
curl "https://api.example.org/photos/<owner_id>/"
const response = await fetch('https://api.example.org/photos/<owner_id>/', {
method: 'GET',
});
const answer = await response.json();
import requests
response = requests.get(
"https://api.example.org/photos/<owner_id>/",
)
answer = response.json()
Answer · 200
{
"data": [
{
"access": "string",
"alias": "string",
"author": {
"alias": null,
"avatar_urls": null,
"id": null,
"name": null,
"type": null
},
"authorized": {
"add_follower": null,
"administration": null,
"audiences": null,
"block_from_owner": null,
"comment": null,
"composers": null,
"delete": null,
"download": null,
"edit": null,
"hide": null,
"invite": null,
"like": null,
"pin": null,
"quote": null
},
"comment_count": 1,
"content": "string",
"cover_urls": {
"key": null
},
"created_at": "2026-10-27T09:30:00Z",
"deleted": false,
"files": [
null
],
"hidden": false,
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"is_subscribed_by_viewer": false,
"language": "en",
"likes_count": 1,
"link_preview": {
"description": null,
"image": null,
"site_name": null,
"title": null,
"url": null
},
"link_previews": [
null
],
"media_removed": {
"alts": null,
"count": null,
"gone": null
},
"mimetype": "string",
"origin_domain": "string",
"owner": {
"alias": null,
"avatar_urls": null,
"body": null,
"id": null,
"is_following_viewer": null,
"is_leading_viewer": null,
"name": null,
"type": null
},
"parent_id": 42,
"portrait_urls": {
"key": null
},
"quote": {
"post": null,
"state": null
},
"quote_count": 1,
"quote_id": 42,
"repost_count": 1,
"root_id": 42,
"title": "string",
"type": "string",
"uri": "https://example.org/",
"video": {
"duration": null,
"files": null,
"height": null,
"loop": null,
"poster": null,
"width": null
}
}
],
"pagination": {
"limit": 1,
"offset": 1,
"total": 1
}
}
Post photos
/photos/{owner_id}/As JSON naming the images uploaded for it (POST /photos/{owner_id}/uploads), in order: the way to post several. Or as a form carrying one image in file, as older clients do. A title and words are both optional: the pictures are the post.
Who: Somebody signed in, with media:write
Parameters
owner_idintegerrequiredin pathThe profile it is posted on.
Body application/json
allow_downloadbooleanWhether whoever can see it may download it. Left out, the post starts with what the profile it is on says.library_onlybooleanIn the author's media library only: put up from inside the article editor to be shown in an article, and listed and announced nowhere. Only on the author's own profile.location_idslist of integerThe locations its author chose for it, tied to it as it is made, so that it goes to other servers with them: the first as itslocation, all asPlaces in itstag(roadmap row 82, part 3b). Up to five; what is not a location is passed over. At most 5 of them.quote_policystringWho may quote it: "anyone", "followers" or "nobody". Left out, the author's own setting applies. At most 16 characters.reply_accessstringWho may reply: "anyone", "nobody", or any of "followers", "following" and "mentioned" joined by commas. Left out, anyone the profile lets. At most 64 characters.uploadslist of photo.FileRefThe images, in order, each an upload made for this profile.
Body application/x-www-form-urlencoded or multipart/form-data
accessstringWho may see it (permissions.md). The widest the installation allows when left out. One ofpublic,registered,followers,leaders,mutuals,admins,myself.publicunless given.allow_downloadbooleanWhether whoever can see it may download it. Left out, the post starts with what the profile it is on says.alt_textstringWhat the one image of a form post shows.contentstringIts words, as Markdown, if it has any. At most 8000 characters.languagestringThe language it is written in, as a BCP 47 tag: "en", "fr-CA". At most 12 characters.library_onlybooleanIn the author's media library only: put up from inside the article editor to be shown in an article, and listed and announced nowhere. Only on the author's own profile.location_idslist of integerThe locations its author chose for it, tied to it as it is made, so that it goes to other servers with them: the first as itslocation, all asPlaces in itstag(roadmap row 82, part 3b). Up to five; what is not a location is passed over. At most 5 of them.quote_policystringWho may quote it: "anyone", "followers" or "nobody". Left out, the author's own setting applies. At most 16 characters.reply_accessstringWho may reply: "anyone", "nobody", or any of "followers", "following" and "mentioned" joined by commas. Left out, anyone the profile lets. At most 64 characters.titlestringIts title, if it has one. At most 100 characters.
Answers
- 201CreatedMediumNode application/json
- 400the request is not well formed, or a value in it is not one it may be
- 401no token, or one that has expired
- 403the viewer may not post here
- 404there is no such profile
- 422Unprocessable Entityphoto.FilesRefusal application/json
Request
curl -X POST "https://api.example.org/photos/<owner_id>/" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"allow_download": false,
"library_only": false,
"location_ids": [
1
],
"quote_policy": "string",
"reply_access": "string",
"uploads": [
{
"alt_text": "string",
"id": "string",
"upload_id": 42
}
]
}'
const response = await fetch('https://api.example.org/photos/<owner_id>/', {
method: 'POST',
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
"allow_download": false,
"library_only": false,
"location_ids": [
1
],
"quote_policy": "string",
"reply_access": "string",
"uploads": [
{
"alt_text": "string",
"id": "string",
"upload_id": 42
}
]
}),
});
const answer = await response.json();
import requests
response = requests.post(
"https://api.example.org/photos/<owner_id>/",
headers={"Authorization": f"Bearer {token}"},
json={
"allow_download": False,
"library_only": False,
"location_ids": [
1
],
"quote_policy": "string",
"reply_access": "string",
"uploads": [
{
"alt_text": "string",
"id": "string",
"upload_id": 42
}
]
},
)
answer = response.json()
Answer · 201
{
"access": "string",
"alias": "string",
"allow_download": false,
"author": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"authorized": {
"add_follower": false,
"administration": false,
"audiences": [
"string"
],
"block_from_owner": false,
"comment": false,
"composers": [
"string"
],
"delete": false,
"download": false,
"edit": false,
"hide": false,
"invite": false,
"like": false,
"pin": false,
"quote": false
},
"citation_count": 1,
"comment_count": 1,
"comment_status": false,
"content": "string",
"cover_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"created_at": "2026-10-27T09:30:00Z",
"deleted": false,
"draft": false,
"editor": {
"alias": "string",
"avatar_urls": {
"key": null
},
"id": 42,
"name": "string",
"type": "string"
},
"enabled": false,
"files": [
{
"alt_text": "string",
"height": 1,
"id": "string",
"position": 1,
"urls": {
"key": null
},
"width": 1
}
],
"hidden": false,
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"is_subscribed_by_viewer": false,
"language": "en",
"library_only": false,
"likes_count": 1,
"link_preview": {
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
},
"link_previews": [
{
"description": "string",
"image": "string",
"site_name": "string",
"title": "string",
"url": "https://example.org/"
}
],
"media_removed": {
"alts": [
"string"
],
"count": 1,
"gone": false
},
"mimetype": "string",
"origin_domain": "string",
"owner": {
"alias": "string",
"avatar_urls": {
"key": null
},
"body": "string",
"id": 42,
"is_following_viewer": false,
"is_leading_viewer": false,
"name": "string",
"type": "string"
},
"parent_id": 42,
"pinned": false,
"portrait_urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"quote": {
"post": {
"access": null,
"alias": null,
"author": null,
"authorized": null,
"body": null,
"content": null,
"cover_urls": null,
"created_at": null,
"files": null,
"id": null,
"is_liked_by_viewer": null,
"is_reposted_by_viewer": null,
"is_saved_by_viewer": null,
"link_preview": null,
"name": null,
"owner": null,
"portrait_urls": null,
"title": null,
"type": null,
"video": null
},
"state": "string"
},
"quote_count": 1,
"quote_id": 42,
"quote_policy": "string",
"reply_access": "string",
"repost_count": 1,
"root": {
"access": "string",
"alias": "string",
"author": {
"alias": null,
"avatar_urls": null,
"id": null,
"name": null,
"type": null
},
"authorized": {
"add_follower": null,
"administration": null,
"audiences": null,
"block_from_owner": null,
"comment": null,
"composers": null,
"delete": null,
"download": null,
"edit": null,
"hide": null,
"invite": null,
"like": null,
"pin": null,
"quote": null
},
"body": "string",
"content": "string",
"cover_urls": {
"key": null
},
"created_at": "2026-10-27T09:30:00Z",
"files": [
null
],
"id": 42,
"is_liked_by_viewer": false,
"is_reposted_by_viewer": false,
"is_saved_by_viewer": false,
"link_preview": {
"description": null,
"image": null,
"site_name": null,
"title": null,
"url": null
},
"name": "string",
"owner": {
"alias": null,
"avatar_urls": null,
"body": null,
"id": null,
"is_following_viewer": null,
"is_leading_viewer": null,
"name": null,
"type": null
},
"portrait_urls": {
"key": null
},
"title": "string",
"type": "string",
"video": {
"duration": null,
"files": null,
"height": null,
"loop": null,
"poster": null,
"width": null
}
},
"root_id": 42,
"title": "string",
"type": "string",
"updated_at": "2026-10-27T09:30:00Z",
"uri": "https://example.org/",
"video": {
"duration": 1.5,
"files": [
null
],
"height": 1,
"loop": false,
"poster": "string",
"width": 1
},
"view_count": 1
}
Upload an image for a post
/photos/{owner_id}/uploadsOne image a request: a post with several is made from its uploads, so no request carries more than one. For whoever may post on the profile.
Who: Somebody signed in, with media:write
Parameters
owner_idintegerrequiredin pathThe profile the post will be on.
Body multipart/form-data
filefilerequiredThe image: a JPEG or a PNG, of at most 10 MB.
Answers
- 201Createdphoto.Uploaded application/json
- 400Bad Requestphoto.FilesRefusal application/json
- 401no token, or one that has expired
- 403the viewer may not post here
- 404there is no such profile
- 413Request Entity Too Largephoto.FilesRefusal application/json
- 415Unsupported Media Typephoto.FilesRefusal application/json
Request
curl -X POST "https://api.example.org/photos/<owner_id>/uploads" \
-H "Authorization: Bearer $TOKEN" \
-F "file=@photo.jpg"
const form = new FormData();
form.append('file', file);
const response = await fetch('https://api.example.org/photos/<owner_id>/uploads', {
method: 'POST',
headers: { Authorization: `Bearer ${token}` },
body: form,
});
const answer = await response.json();
import requests
response = requests.post(
"https://api.example.org/photos/<owner_id>/uploads",
headers={"Authorization": f"Bearer {token}"},
data={},
files={"file": open("photo.jpg", "rb")},
)
answer = response.json()
Answer · 201
{
"height": 1,
"upload_id": 42,
"urls": {
"key": {
"size": null,
"url": "https://example.org/"
}
},
"width": 1
}
Written by Claude, reviewed by Rastin Mehr · About this