Skip to main content

Introduction

Kitsu provides a comprehensive REST API for managing production data. The frontend uses a modular API client architecture built on top of Superagent for HTTP requests and Socket.io for real-time updates.

API Client Architecture

The API client is organized into specialized modules, each handling a specific domain:
src/store/api/
├── client.js          # Base HTTP client
├── assets.js          # Asset operations
├── shots.js           # Shot operations
├── tasks.js           # Task and comment operations
├── entities.js        # Generic entity operations
├── files.js           # File and preview operations
├── people.js          # Team member operations
├── productions.js     # Production/project operations
└── ...                # Additional modules

Base Client

All API modules use the base client (src/store/api/client.js) which provides:

HTTP Methods

GET, POST, PUT, DELETE with callback and promise-based interfaces

Authentication

Automatic 401 handling and redirect to login

Error Handling

Centralized error handling and reporting

File Uploads

File upload support with progress tracking

Client Methods

The base client provides both callback-based and promise-based methods:
import client from '@/store/api/client'

// GET request
const data = await client.pget('/api/data/tasks')

// POST request
const result = await client.ppost('/api/data/tasks', taskData)

// PUT request
const updated = await client.pput('/api/data/tasks/123', updates)

// DELETE request
const deleted = await client.pdel('/api/data/tasks/123')

API Base URL

The API communicates with the Zou backend:
  • Development: Configured via KITSU_API_TARGET environment variable
  • Production: Uses the same host as the frontend (/api)

API Endpoints Structure

Kitsu API endpoints follow a consistent pattern:
Used for CRUD operations on entities:
GET    /api/data/tasks          # List tasks
GET    /api/data/tasks/:id      # Get task
POST   /api/data/tasks          # Create task
PUT    /api/data/tasks/:id      # Update task
DELETE /api/data/tasks/:id      # Delete task
Used for complex operations:
POST /api/actions/tasks/:id/comment
POST /api/actions/tasks/:id/subscribe
PUT  /api/actions/persons/:id/assign
Used for file uploads:
POST /api/pictures/preview-files/:id
POST /api/pictures/thumbnails/persons/:id
Authentication operations:
POST /api/auth/login
GET  /api/auth/logout
GET  /api/auth/authenticated

Using API Modules

API modules should always be called from Vuex actions, not directly from components:
// src/store/modules/tasks.js
import tasksApi from '@/store/api/tasks'

const actions = {
  async loadTask({ commit }, taskId) {
    try {
      const task = await tasksApi.getTask(taskId)
      commit(LOAD_TASK_END, task)
      return task
    } catch (err) {
      console.error('Failed to load task:', err)
      throw err
    }
  }
}
Always use Vuex actions for API calls to ensure proper state management and error handling.

Error Handling

The API client automatically handles authentication errors:
src/store/api/client.js
ppost(path, data) {
  return superagent
    .post(path)
    .send(data)
    .then(res => res?.body)
    .catch(err => {
      // Automatic redirect on 401
      if (res?.statusCode === 401) {
        errors.backToLogin()
      }
      throw err
    })
}
In your actions, handle other errors appropriately:
actions: {
  async loadTasks({ commit }, filters) {
    try {
      const tasks = await tasksApi.getTasks(filters)
      commit(LOAD_TASKS_END, tasks)
      return tasks
    } catch (err) {
      // Handle network errors, server errors, etc.
      console.error('Failed to load tasks:', err)
      commit(LOAD_TASKS_ERROR, err.message)
      throw err
    }
  }
}

Query Parameters

Use the buildQueryString helper for URL parameters:
import { buildQueryString } from '@/lib/query'
import client from '@/store/api/client'

export default {
  getTasks(filters) {
    const path = '/api/data/tasks'
    return client.pget(buildQueryString(path, filters))
  }
}
Example usage:
const filters = {
  project_id: '123',
  task_status_id: '456',
  limit: 100
}

const tasks = await tasksApi.getTasks(filters)
// GET /api/data/tasks?project_id=123&task_status_id=456&limit=100

Real-time Updates

Kitsu uses Socket.io for real-time collaboration:
// Socket is available in Vuex store
store.$socket.on('task:update', (data) => {
  store.commit(UPDATE_TASK, data)
})

store.$socket.on('comment:new', (data) => {
  store.commit(NEW_COMMENT, data)
})

store.$socket.on('preview:ready', (data) => {
  store.commit(UPDATE_PREVIEW, data)
})
The socket connection is established in src/main.js:
import VueWebsocket from 'vue-websocket-next'
import IO from 'socket.io-client'

app.use(VueWebsocket, IO, '/events')
store.$socket = app.config.globalProperties.$socket

Common Patterns

Many endpoints support a relations=true parameter:
client.getModel(modelName, modelId, relations = false) {
  let path = `/api/data/${modelName}/${modelId}`
  if (relations) path += '?relations=true'
  return client.pget(path)
}
Example:
const task = await client.getModel('tasks', taskId, true)
// Returns task with populated assignees, task_type, etc.
Global search across entities:
client.searchData(query, limit, offset, index_names, productionId) {
  const path = '/api/data/search'
  const data = { query, limit, offset, index_names }
  if (productionId !== 'all') {
    data.project_id = productionId
  }
  return client.ppost(path, data)
}

Events

Fetch recent events for synchronization:
client.getEvents(after, before, limit, lastEventId = null) {
  let path = `/api/data/events/last?after=${after}&before=${before}&limit=${limit}`
  if (lastEventId) {
    path += `&cursor_event_id=${lastEventId}`
  }
  return client.pget(path)
}

Best Practices

Use Vuex Actions

Always call API methods from Vuex actions, never directly from components

Handle Errors

Implement proper error handling and user feedback

Type Safety

Validate API responses before committing to state

Optimize Requests

Cache data when appropriate and avoid unnecessary API calls

Next Steps

Explore specific API modules:

Authentication

Learn about authentication and session management

Entities

Work with assets, shots, and other entities

Tasks

Manage tasks and comments

Files

Handle file uploads and previews

Build docs developers (and LLMs) love