Build with the Makrly API
Build product communication workflows on top of Makrly. Generate reviewed social-ready drafts, manage changelog entries, and connect release communication to your own systems.
Quick Start
Get your API key
Go to Settings → API in your dashboard and create a new API key.
Make your first request
curl -H "Authorization: Bearer mk_live_your_key_here" \ https://www.makrly.com/api/v1/repos
Get your repos back
{
"data": [
{
"id": 1,
"fullName": "you/your-repo",
"notableCommitCount": 42,
"changelogEntryCount": 15
}
]
}Authentication
All API requests require a Bearer token in the Authorization header:
Authorization: Bearer mk_live_your_key_here
API keys start with mk_live_ and are shown once on creation.
API keys are available on paid plans. You can create up to 10 active keys, scoped to specific repos and permissions.
Available Scopes
changelog:readRead changelog entrieschangelog:writeCreate, update, delete entriessettings:readRead widget settingssettings:writeUpdate widget settingsanalytics:readRead analytics dataServer-side only: API keys are designed for server-to-server requests. Do not expose your key in client-side code (browsers, mobile apps), even though API responses include CORS headers for integration compatibility.
Base URL
https://www.makrly.com/api/v1
Endpoints
Repositories
/api/v1/reposList your tracked repositories
{
"data": [
{
"id": 1,
"name": "my-app",
"fullName": "username/my-app",
"isPrivate": false,
"isActive": true,
"notableCommitCount": 42,
"changelogEntryCount": 15,
"lastSyncedAt": "2025-01-15T10:00:00Z"
}
]
}/api/v1/repos/:repoIdGet a single repository
Posts
/api/v1/repos/:repoId/posts?platform=x&page=1&limit=20List generated draft posts for a repo
{
"data": [
{
"id": 1,
"platform": "x",
"content": "Shipped granular team permissions...",
"createdAt": "2025-01-15T10:00:00Z",
"commit": {
"id": 42,
"sha": "abc123",
"message": "feat: add granular team permissions"
}
}
],
"meta": { "page": 1, "limit": 20, "total": 5, "totalPages": 1 }
}/api/v1/posts/generateGenerate draft posts from custom text
{
"content": "Just shipped a new feature...",
"repoId": 1,
"provider": "openai",
"model": "gpt-4o"
}{
"data": {
"short": "Shipped granular team permissions.",
"thread": ["Post 1...", "Post 2..."],
"linkedin": "Excited to announce...",
"facebookProfile": "New feature alert!...",
"facebookPage": "We're thrilled..."
}
}/api/v1/posts/:idGet a single post
/api/v1/posts/:idUpdate a post's content
{ "content": "Updated post text..." }Changelog Entries
/api/v1/changelog/entries?repoId=1&status=published&cursor=abc&limit=20List changelog entries (scope: changelog:read)
{
"entries": [{ "id": "abc", "title": "Team permissions", "categories": ["new"], ... }],
"nextCursor": "def",
"hasMore": true
}/api/v1/changelog/entriesCreate a changelog entry (scope: changelog:write)
{
"repoId": 1,
"title": "Team permissions",
"content": "Admins can now invite teammates with scoped access.",
"summary": "Added granular team permissions",
"categories": ["new"],
"publish": true,
"publishedAt": "2025-01-15T10:00:00Z"
}/api/v1/changelog/entries/:idGet a single entry (scope: changelog:read)
/api/v1/changelog/entries/:idUpdate an entry (scope: changelog:write)
{
"title": "Updated Title",
"categories": ["improved"],
"publish": true,
"pin": true
}/api/v1/changelog/entries/:idDelete an entry (scope: changelog:write)
Changelog Settings
/api/v1/changelog/settings?repoId=1Get widget settings (scope: settings:read)
/api/v1/changelog/settingsUpdate widget settings (scope: settings:write)
{
"repoId": 1,
"theme": "dark",
"position": "bottom-right",
"primaryColor": "#6366f1",
"isPublic": true
}Commits
/api/v1/repos/:repoId/commits?notable=true&page=1&limit=20List commits for a repo
Analytics
/api/v1/analytics?repoId=1&range=30dGet unified analytics (scope: analytics:read, Indie plan or higher)
Rate Limits
Rate limit info is included in every response via headers:
X-RateLimit-Limit: 100 X-RateLimit-Remaining: 99 X-RateLimit-Reset: 1705312800
X-RateLimit-Reset is a Unix timestamp (seconds) for when the window resets.
Errors
All errors return a consistent format:
{
"error": "Repository not found",
"code": "not_found"
}| Code | Status | Description |
|---|---|---|
| unauthenticated | 401 | Missing authentication (no API key or session) |
| missing_auth | 401 | Missing or malformed Authorization header |
| invalid_format | 401 | Invalid API key format |
| invalid_key | 401 | API key not found in database |
| key_revoked | 401 | API key has been revoked |
| key_expired | 401 | API key has expired |
| key_in_query | 401 | API key sent as query param (use header instead) |
| insufficient_scope | 403 | API key lacks required scope |
| repo_scope_mismatch | 403 | Repo-scoped key accessing wrong repo |
| upgrade_required | 403 | The endpoint requires a paid plan |
| not_found | 404 | Resource not found or not owned by you |
| repo_not_found | 404 | Repository not found or not owned by you |
| validation_error | 400 | Invalid request parameters |
| missing_repo_id | 400 | repoId is required for account-scoped keys |
| configuration_error | 400 | Required account configuration is missing |
| rate_limited | 429 | Too many requests (Retry-After header included) |
| server_error | 500 | Internal server error |
| internal_error | 500 | Internal server error |
Code Examples
JavaScript (fetch)
const response = await fetch("https://www.makrly.com/api/v1/repos", {
headers: {
"Authorization": "Bearer mk_live_your_key_here"
}
});
const { data } = await response.json();
console.log(data); // Your reposPython (requests)
import requests
response = requests.get(
"https://www.makrly.com/api/v1/repos",
headers={"Authorization": "Bearer mk_live_your_key_here"}
)
data = response.json()["data"]
print(data) # Your reposGenerate draft posts from text
curl -X POST https://www.makrly.com/api/v1/posts/generate \
-H "Authorization: Bearer mk_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"content": "Shipped granular team permissions for my SaaS app.",
"repoId": 1
}'Create a changelog entry
curl -X POST https://www.makrly.com/api/v1/changelog/entries \
-H "Authorization: Bearer mk_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"repoId": 1,
"title": "Team permissions",
"content": "Admins can now invite teammates with scoped access.",
"categories": ["new"],
"publish": true,
"publishedAt": "2025-01-15T10:00:00Z"
}'