9.3 KiB
API Documentation
Overview
This document describes the Mastodon API integration used in My ActivityPub app. The app communicates with Mastodon-compatible servers using their REST API v1.
Base URL
Default: https://mastodon.social/
You can configure this to any Mastodon or ActivityPub-compatible instance.
Authentication
Currently, the app accesses public endpoints that don't require authentication. Future versions will implement OAuth 2.0 for authenticated requests.
Endpoints
1. Get Public Timeline
Retrieve statuses from the public timeline.
Endpoint: GET /api/v1/timelines/public
Parameters:
limit(integer, optional): Maximum number of results. Default: 20local(boolean, optional): Show only local statuses. Default: falsemax_id(string, optional): Return results older than this IDsince_id(string, optional): Return results newer than this IDmin_id(string, optional): Return results immediately newer than this ID
Example Request:
GET https://mastodon.social/api/v1/timelines/public?limit=20&local=false
Response: Array of Status objects
Example Response:
[
{
"id": "109382159165398564",
"created_at": "2022-11-23T07:49:01.940Z",
"content": "<p>Hello world!</p>",
"account": {
"id": "109382",
"username": "alice",
"display_name": "Alice",
"avatar": "https://...",
...
},
"media_attachments": [],
"favourites_count": 5,
"reblogs_count": 2,
"replies_count": 1,
...
}
]
2. Get Instance Information
Get information about the Mastodon instance.
Endpoint: GET /api/v1/instance
Parameters: None
Example Request:
GET https://mastodon.social/api/v1/instance
Response: Instance object
Example Response:
{
"uri": "mastodon.social",
"title": "Mastodon",
"short_description": "The original server operated by the Mastodon gGmbH non-profit",
"description": "...",
"version": "4.0.0",
"languages": ["en"],
"thumbnail": "https://..."
}
3. Get Account
Get account information.
Endpoint: GET /api/v1/accounts/:id
Parameters:
id(string, required): Account ID
Example Request:
GET https://mastodon.social/api/v1/accounts/109382
Response: Account object
Example Response:
{
"id": "109382",
"username": "alice",
"acct": "alice",
"display_name": "Alice",
"locked": false,
"bot": false,
"created_at": "2022-11-23T07:49:01.940Z",
"note": "<p>Bio goes here</p>",
"url": "https://mastodon.social/@alice",
"avatar": "https://...",
"header": "https://...",
"followers_count": 100,
"following_count": 50,
"statuses_count": 500
}
4. Get Account Statuses
Get statuses posted by an account.
Endpoint: GET /api/v1/accounts/:id/statuses
Parameters:
id(string, required): Account IDlimit(integer, optional): Maximum number of results. Default: 20max_id(string, optional): Return results older than this IDsince_id(string, optional): Return results newer than this IDexclude_replies(boolean, optional): Skip statuses that reply to other statusesexclude_reblogs(boolean, optional): Skip statuses that are reblogs of other statusesonly_media(boolean, optional): Show only statuses with media attached
Example Request:
GET https://mastodon.social/api/v1/accounts/109382/statuses?limit=20
Response: Array of Status objects
Data Models
Status
Represents a post/toot on Mastodon.
Properties:
{
id: string // Unique identifier
created_at: string // ISO 8601 datetime
content: string // HTML content
account: Account // Account that posted this status
media_attachments: Array // Media attachments
reblog: Status | null // If this is a reblog, the original status
favourites_count: number // Number of favorites
reblogs_count: number // Number of reblogs/boosts
replies_count: number // Number of replies
favourited: boolean // Has the current user favorited this?
reblogged: boolean // Has the current user reblogged this?
url: string | null // URL to the status
visibility: string // Visibility level (public, unlisted, private, direct)
}
Account
Represents a user account.
Properties:
{
id: string // Unique identifier
username: string // Username (without @domain)
acct: string // Full username (@username@domain)
display_name: string // Display name
avatar: string // URL to avatar image
header: string // URL to header image
note: string // Bio/description (HTML)
url: string | null // URL to profile page
followers_count: number // Number of followers
following_count: number // Number of accounts being followed
statuses_count: number // Number of statuses posted
bot: boolean // Is this a bot account?
locked: boolean // Does this account require follow requests?
}
MediaAttachment
Represents media files attached to statuses.
Properties:
{
id: string // Unique identifier
type: string // Type: image, video, gifv, audio, unknown
url: string // URL to the media file
preview_url: string | null // URL to the preview/thumbnail
remote_url: string | null // Remote URL if the media is from another server
description: string | null // Alt text description
}
Instance
Represents a Mastodon instance.
Properties:
{
uri: string // Domain name
title: string // Instance name
description: string // Long description (HTML)
short_description: string // Short description (plaintext)
version: string // Mastodon version
thumbnail: string | null // URL to thumbnail image
languages: Array<string> // ISO 639 Part 1-5 language codes
email: string | null // Contact email
contact_account: Account // Contact account
}
Error Handling
The API returns standard HTTP status codes:
200 OK- Request succeeded400 Bad Request- Invalid parameters401 Unauthorized- Authentication required403 Forbidden- Access denied404 Not Found- Resource not found429 Too Many Requests- Rate limit exceeded500 Internal Server Error- Server error503 Service Unavailable- Server temporarily unavailable
Error Response Format:
{
"error": "Error message here"
}
Rate Limiting
Mastodon implements rate limiting to prevent abuse. Limits vary by instance but typically:
- 300 requests per 5 minutes for authenticated requests
- Lower limits for unauthenticated requests
Rate limit information is returned in response headers:
X-RateLimit-Limit- Maximum number of requestsX-RateLimit-Remaining- Remaining requests in current windowX-RateLimit-Reset- Time when the limit resets (ISO 8601)
Best Practices
- Respect Rate Limits: Implement exponential backoff when hitting rate limits
- Cache Responses: Cache instance info and other static data
- Use Pagination: Use
max_idandsince_idfor efficient pagination - Handle Errors: Always handle network errors and API errors gracefully
- Validate Input: Validate user input before making API calls
- Use HTTPS: Always use HTTPS for API requests
- Set User-Agent: Include a descriptive User-Agent header
Implementation in the App
Service Layer
MastodonApiService.kt defines the API interface using Retrofit annotations:
interface MastodonApiService {
@GET("api/v1/timelines/public")
suspend fun getPublicTimeline(
@Query("limit") limit: Int = 20,
@Query("local") local: Boolean = false
): Response<List<Status>>
// Other endpoints...
}
Repository Layer
MastodonRepository.kt wraps API calls with error handling:
suspend fun getPublicTimeline(limit: Int = 20, local: Boolean = false): Result<List<Status>> {
return withContext(Dispatchers.IO) {
try {
val response = apiService.getPublicTimeline(limit, local)
if (response.isSuccessful) {
Result.success(response.body() ?: emptyList())
} else {
Result.failure(Exception("Error: ${response.code()}"))
}
} catch (e: Exception) {
Result.failure(e)
}
}
}
ViewModel Layer
TimelineViewModel.kt manages UI state and calls repository methods:
fun loadTimeline() {
viewModelScope.launch {
_uiState.value = TimelineUiState.Loading
repository.getPublicTimeline().fold(
onSuccess = { statuses ->
_uiState.value = TimelineUiState.Success(statuses)
},
onFailure = { error ->
_uiState.value = TimelineUiState.Error(error.message ?: "Unknown error")
}
)
}
}