@lap v0.3
# Machine-readable API spec. Each @endpoint block is one API call.
@api Forem API V1
@base https://dev.to/api
@version 1.0.0
@auth ApiKey api-key in header
@endpoints 65
@hint download_for_search
@toc api(65)

@endpoint GET /api/agent_sessions
@returns(200)
@errors {401}

@endpoint POST /api/agent_sessions
@required {curated_data: str}
@optional {title: str, s3_key: str, tool_name: str(claude_code/codex/gemini_cli/github_copilot/pi)}
@returns(201) {id: int(int64), slug: str, title: str, tool_name: str, total_messages: int(int32), published: bool, created_at: str(date-time), updated_at: str(date-time), url: str(url)}
@errors {401, 422}

@endpoint GET /api/agent_sessions/{id}
@required {id: str}
@returns(200) {id: int(int64), slug: str, title: str, tool_name: str, total_messages: int(int32), curated_count: int(int32), published: bool, metadata: map?, messages: [map], slices: [map], created_at: str(date-time), updated_at: str(date-time), url: str(url)}
@errors {401, 404}

@endpoint POST /api/articles
@optional {article: map{title: str, body_markdown: str, published: bool, series: str, main_image: str, canonical_url: str, description: str, tags: str, organization_id: int}}
@returns(201)
@errors {401, 422}

@endpoint GET /api/articles
@optional {page: int(int32)=1, per_page: int(int32)=30, tag: str, tags: str, tags_exclude: str, username: str, state: str(fresh/rising/all), top: int(int32), collection_id: int(int32)}
@returns(200)

@endpoint GET /api/articles/latest
@optional {page: int(int32)=1, per_page: int(int32)=30}
@returns(200)

@endpoint GET /api/articles/{id}
@required {id: int}
@returns(200)
@errors {404}

@endpoint PUT /api/articles/{id}
@required {id: int(int32)}
@optional {article: map{title: str, body_markdown: str, published: bool, series: str, main_image: str, canonical_url: str, description: str, tags: str, organization_id: int}}
@returns(200)
@errors {401, 404, 422}

@endpoint GET /api/articles/{username}/{slug}
@required {username: str, slug: str}
@returns(200)
@errors {404}

@endpoint GET /api/articles/me
@optional {page: int(int32)=1, per_page: int(int32)=30}
@returns(200)
@errors {401}

@endpoint GET /api/articles/me/published
@optional {page: int(int32)=1, per_page: int(int32)=30}
@returns(200)
@errors {401}

@endpoint GET /api/articles/me/unpublished
@optional {page: int(int32)=1, per_page: int(int32)=30}
@returns(200)
@errors {401}

@endpoint GET /api/articles/me/all
@optional {page: int(int32)=1, per_page: int(int32)=30}
@returns(200)
@errors {401}

@endpoint PUT /api/articles/{id}/unpublish
@required {id: int(int32)}
@optional {note: str}
@returns(204)
@errors {401, 404}

@endpoint GET /api/segments
@optional {per_page: int(int32)=30}
@returns(200)
@errors {401}

@endpoint POST /api/segments
@returns(201)
@errors {401}

@endpoint GET /api/segments/{id}
@required {id: int(int32)}
@returns(200)
@errors {401, 404}

@endpoint DELETE /api/segments/{id}
@required {id: int(int32)}
@returns(200)
@errors {401, 404, 409}

@endpoint GET /api/segments/{id}/users
@required {id: int(int32)}
@optional {per_page: int(int32)=30}
@returns(200)
@errors {401, 404}

@endpoint PUT /api/segments/{id}/add_users
@required {id: int(int32)}
@optional {user_ids: [int]}
@returns(200)
@errors {401, 404, 422}

@endpoint PUT /api/segments/{id}/remove_users
@required {id: int(int32)}
@optional {user_ids: [int]}
@returns(200)
@errors {401, 404, 422}

@endpoint GET /api/billboards
@returns(200)
@errors {401}

@endpoint POST /api/billboards
@returns(201)
@errors {401, 422}

@endpoint GET /api/billboards/{id}
@required {id: int(int32)}
@returns(200)
@errors {401, 404}

@endpoint PUT /api/billboards/{id}
@required {id: int(int32)}
@returns(200)
@errors {401, 404}

@endpoint PUT /api/billboards/{id}/unpublish
@required {id: int(int32)}
@returns(204)
@errors {401, 404}

@endpoint GET /api/comments
@optional {page: int(int32)=1, per_page: int(int32)=30, a_id: str, p_id: str, page: str}
@returns(200)
@errors {404}

@endpoint GET /api/comments/{id}
@required {id: int}
@returns(200)
@errors {404}

@endpoint GET /api/follows/tags
@returns(200)
@errors {401}

@endpoint GET /api/followers/users
@optional {page: int(int32)=1, per_page: int(int32)=30, sort: str}
@returns(200)
@errors {401}

@endpoint GET /api/organizations/{username}
@required {username: str}
@returns(200)
@errors {404}

@endpoint GET /api/organizations/{organization_id_or_username}/users
@required {organization_id_or_username: str}
@optional {page: int(int32)=1, per_page: int(int32)=30}
@returns(200)
@errors {404}

@endpoint GET /api/organizations/{organization_id_or_username}/articles
@required {organization_id_or_username: str}
@optional {page: int(int32)=1, per_page: int(int32)=30}
@returns(200)
@errors {404}

@endpoint GET /api/organizations
@optional {page: int(int32)=1, per_page: int(int32)=10}
@returns(200)

@endpoint POST /api/organizations
@optional {type_of: str, username: str, name: str, summary: str, twitter_username: str, github_username: str, url: str, location: str, joined_at: str, tech_stack: str, tag_line: str, story: str}
@returns(201)
@errors {401, 422}

@endpoint GET /api/organizations/{id}
@required {id: int}
@returns(200)
@errors {404}

@endpoint PUT /api/organizations/{id}
@required {id: int(int32)}
@optional {type_of: str, username: str, name: str, summary: str, twitter_username: str, github_username: str, url: str, location: str, joined_at: str, tech_stack: str, tag_line: str, story: str}
@returns(200)
@errors {401, 404, 422}

@endpoint DELETE /api/organizations/{id}
@required {id: int(int32)}
@returns(200)
@errors {401}

@endpoint GET /api/pages
@returns(200)

@endpoint POST /api/pages
@optional {title: str, slug: str, description: str, body_markdown: str, body_json: str, is_top_level_path: bool, template: str(contained/full_within_layout/nav_bar_included/json/css/txt)=contained}
@returns(200)
@errors {401, 422}

@endpoint GET /api/pages/{id}
@required {id: int(int32)}
@returns(200) {title: str, slug: str, description: str, body_markdown: str?, body_json: str?, is_top_level_path: bool, social_image: map?, template: str}

@endpoint PUT /api/pages/{id}
@required {id: int(int32), title: str, slug: str, description: str, template: str(contained/full_within_layout/nav_bar_included/json/css/txt)=contained}
@optional {body_markdown: str, body_json: str, is_top_level_path: bool, social_image: map}
@returns(200) {title: str, slug: str, description: str, body_markdown: str?, body_json: str?, is_top_level_path: bool, social_image: map?, template: str}
@errors {401, 422}

@endpoint DELETE /api/pages/{id}
@required {id: int(int32)}
@returns(200) {title: str, slug: str, description: str, body_markdown: str?, body_json: str?, is_top_level_path: bool, social_image: map?, template: str}
@errors {401, 422}

@endpoint GET /api/podcast_episodes
@optional {page: int(int32)=1, per_page: int(int32)=30, username: str}
@returns(200)
@errors {404}

@endpoint GET /api/profile_images/{username}
@required {username: str}
@returns(200)
@errors {404}

@endpoint POST /api/reactions/toggle
@required {category: str(like/unicorn/exploding_head/raised_hands/fire), reactable_id: int(int32), reactable_type: str(Comment/Article/User)}
@returns(200)
@errors {401}

@endpoint POST /api/reactions
@required {category: str(like/unicorn/exploding_head/raised_hands/fire), reactable_id: int(int32), reactable_type: str(Comment/Article/User)}
@returns(200)
@errors {401}

@endpoint GET /api/readinglist
@optional {page: int(int32)=1, per_page: int(int32)=30}
@returns(200)
@errors {401}

@endpoint GET /api/surveys
@optional {page: int(int32)=1, per_page: int(int32)=30, active: bool}
@returns(200)
@errors {401}

@endpoint GET /api/surveys/{id_or_slug}
@required {id_or_slug: str}
@returns(200)
@errors {401, 404}

@endpoint GET /api/surveys/{id_or_slug}/poll_votes
@required {id_or_slug: str}
@optional {per_page: int(int32)=30, after: int}
@returns(200)
@errors {401, 404}

@endpoint GET /api/surveys/{id_or_slug}/poll_text_responses
@required {id_or_slug: str}
@optional {per_page: int(int32)=30, after: int}
@returns(200)
@errors {401, 404}

@endpoint GET /api/tags
@optional {page: int(int32)=1, per_page: int(int32)=10}
@returns(200)

@endpoint PUT /api/users/{id}/suspend
@required {id: int(int32)}
@returns(204)
@errors {401, 404}

@endpoint PUT /api/users/{id}/limited
@required {id: int(int32)}
@returns(204)
@errors {401, 404}

@endpoint DELETE /api/users/{id}/limited
@required {id: int(int32)}
@returns(204)
@errors {401, 404}

@endpoint PUT /api/users/{id}/spam
@required {id: int(int32)}
@returns(204)
@errors {401, 404}

@endpoint DELETE /api/users/{id}/spam
@required {id: int(int32)}
@returns(204)
@errors {401, 404}

@endpoint PUT /api/users/{id}/trusted
@required {id: int(int32)}
@returns(204)
@errors {401, 404}

@endpoint DELETE /api/users/{id}/trusted
@required {id: int(int32)}
@returns(204)
@errors {401, 404}

@endpoint GET /api/users/me
@returns(200)
@errors {401}

@endpoint GET /api/users/{id}
@required {id: str}
@returns(200)

@endpoint PUT /api/users/{id}/unpublish
@required {id: int(int32)}
@returns(204)
@errors {401, 404}

@endpoint POST /api/admin/users
@optional {email: str, name: str}
@returns(200)
@errors {401, 422}

@endpoint GET /api/videos
@optional {page: int(int32)=1, per_page: int(int32)=24}
@returns(200)

@end
