Docs

API Overview

RESTful API for programmatic access to Habito.

Habito provides a comprehensive REST API for building integrations, automations, and custom tools. Access all features programmatically using standard HTTP methods and JSON payloads.

Base URL

All API requests are made to:

https://habito.ar/api

Authentication

API requests require authentication using an API key. Generate keys from your profile page.

Header Format:

Authorization: Bearer YOUR_API_KEY_HERE

Example request:

curl https://habito.ar/api/me \
  -H "Authorization: Bearer hab_your_api_key_here"
Keep API keys secret! Never commit them to version control or expose them in client-side code.

Rate Limits

API requests are rate limited to prevent abuse:

  • 100 requests per minute per API key
  • 1,000 requests per hour per API key
  • 10,000 requests per day per API key

Rate limit headers are included in responses:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1609459200

Response Format

All responses use JSON format with consistent structure.

Success Response:

{
  "data": {
    "id": "uuid",
    "name": "Example",
    // ... resource fields
  }
}

List Response:

{
  "data": [
    { "id": "1", "name": "Item 1" },
    { "id": "2", "name": "Item 2" }
  ],
  "meta": {
    "total": 2,
    "page": 1,
    "perPage": 20
  }
}

Error Response:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Title is required",
    "details": {
      "field": "title",
      "rule": "required"
    }
  }
}

HTTP Status Codes

CodeMeaningWhen Used
200OKSuccessful GET, PATCH request
201CreatedSuccessful POST request
204No ContentSuccessful DELETE request
400Bad RequestInvalid request payload
401UnauthorizedMissing or invalid API key
403ForbiddenInsufficient permissions
404Not FoundResource doesn't exist
422Unprocessable EntityValidation failed
429Too Many RequestsRate limit exceeded
500Internal Server ErrorServer error

API Endpoints

User & Profile

MethodEndpointDescription
GET/api/meGet authenticated user

Tasks

MethodEndpointDescription
GET/api/tasksList tasks
POST/api/tasksCreate task
GET/api/tasks/:idGet task details
PATCH/api/tasks/:idUpdate task
DELETE/api/tasks/:idArchive task
POST/api/tasks/:id/completeComplete task

Teams

MethodEndpointDescription
GET/api/teamsList teams
POST/api/teamsCreate team
GET/api/teams/:idGet team details
POST/api/teams/joinJoin team
DELETE/api/teams/:id/leaveLeave team

Projects

MethodEndpointDescription
GET/api/projectsList projects
POST/api/projectsCreate project
GET/api/projects/:idGet project details
PATCH/api/projects/:idUpdate project

Issues

MethodEndpointDescription
GET/api/tasksList issues
POST/api/tasksCreate issue
GET/api/tasks/:idGet issue details
PATCH/api/tasks/:idUpdate issue
GET/api/tasks/searchSearch issues

Comments

MethodEndpointDescription
POST/api/tasks/:id/commentsCreate comment
PATCH/api/tasks/:id/comments/:commentIdEdit comment
DELETE/api/tasks/:id/comments/:commentIdDelete comment

Pagination

List endpoints support pagination using query parameters:

GET /api/tasks?page=2&limit=50

Parameters:

  • page: Page number (default: 1)
  • limit: Items per page (default: 20, max: 100)

Response includes pagination metadata:

{
  "data": [...],
  "meta": {
    "total": 150,
    "page": 2,
    "perPage": 50,
    "totalPages": 3
  }
}

Filtering

Many endpoints support filtering via query parameters:

GET /api/tasks?type=habit&difficulty=medium
GET /api/tasks?status=in_progress&priority=high
GET /api/projects?teamId=uuid

Sorting

Sort results using the sort parameter:

GET /api/tasks?sort=-createdAt
GET /api/tasks?sort=priority,-updatedAt

Sort syntax:

  • Field name: ascending order (sort=name)
  • - prefix: descending order (sort=-createdAt)
  • Multiple fields: comma-separated (sort=priority,-createdAt)

Timestamps

All timestamps use ISO 8601 format in UTC:

{
  "createdAt": "2024-01-15T10:30:00.000Z",
  "updatedAt": "2024-01-20T14:45:30.000Z"
}

Webhooks (Coming Soon)

Subscribe to events and receive HTTP callbacks when they occur:

  • task.completed
  • level.up
  • streak.milestone
  • issue.created
  • issue.updated

SDKs (Coming Soon)

Official client libraries:

  • JavaScript/TypeScript
  • Python
  • Go
  • Ruby

Examples

Create a Task

curl -X POST https://habito.ar/api/tasks \
  -H "Authorization: Bearer hab_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Morning workout",
    "type": "habit",
    "difficulty": "medium",
    "isPositive": true
  }'

Complete a Task

curl -X POST https://habito.ar/api/tasks/uuid/complete \
  -H "Authorization: Bearer hab_your_key"

Create an Issue

curl -X POST https://habito.ar/api/tasks \
  -H "Authorization: Bearer hab_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "projectId": "project-uuid",
    "title": "Add dark mode",
    "priority": "high",
    "status": "todo"
  }'

Search Issues

curl "https://habito.ar/api/tasks/search?q=authentication&projectId=uuid" \
  -H "Authorization: Bearer hab_your_key"

Error Handling

Handle errors gracefully in your applications:

try {
  const response = await fetch('https://habito.ar/api/tasks', {
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    },
    method: 'POST',
    body: JSON.stringify(taskData)
  })

  if (!response.ok) {
    const error = await response.json()
    console.error('API Error:', error)
    // Handle specific error codes
    if (response.status === 401) {
      // Invalid API key
    } else if (response.status === 422) {
      // Validation error
    }
  }

  const data = await response.json()
  return data
} catch (error) {
  console.error('Network error:', error)
}

Best Practices

  1. Cache responses when data doesn't change frequently
  2. Batch requests to minimize API calls
  3. Handle rate limits gracefully with exponential backoff
  4. Validate data before sending to avoid 422 errors
  5. Store API keys securely in environment variables
  6. Use webhooks instead of polling (when available)
  7. Implement retries for transient errors (500, 503)

Next Steps

Need Help? Join our Discord community or visit GitHub for support.