Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

For Project Owners & Managers

Alloy gives project owners and managers full control over their projects through an API-first approach. No dashboards to click through, no forms to fill out — every action is a single API call or MCP command. This guide covers the end-to-end workflow: setting up projects, managing backlogs, running sprints, tracking budgets, and reporting to stakeholders.

1. Why Alloy for Project Managers

Traditional tools bury project management behind UIs that break your flow. You switch context to update a board, chase engineers for status updates, and manually assemble sprint reports. Alloy is different:

  • API-first. Every operation — creating tickets, starting sprints, pulling reports — is a single API call. Script it, schedule it, or run it from the terminal.
  • MCP integration. Use natural language via the MCP server to manage your project. Ask your AI assistant to create sprints, assign tickets, or get a project summary without memorizing endpoints.
  • Workflow enforcement. Define exactly which status transitions are allowed. Strict mode rejects invalid moves — no more tickets jumping from Backlog to Done.
  • Budget tracking built in. Projects carry budget_cents and capitalization_type fields. Track spend against budget as time entries are approved.
  • Multi-tenant isolation. Your organization’s data is isolated at the database level. Project members see only what they should.

2. Creating and Configuring a Project

Every project starts with a name, a key (for ticket prefixes), and an organization:

curl -s -X POST "$BASE_URL/api/v1/projects" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d "{
    \"name\": \"Website Redesign\",
    \"key\": \"WEB\",
    \"org_id\": \"$ORG_ID\"
  }" | jq .
{
  "id": "...",
  "org_id": "...",
  "name": "Website Redesign",
  "key": "WEB",
  "created_at": "...",
  "updated_at": "..."
}

Update a project to add budget tracking and capitalization metadata:

curl -s -X PATCH "$BASE_URL/api/v1/projects/$PROJECT_ID" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "budget_cents": 5000000,
    "capitalization_type": "Capex",
    "development_phase": "AppDevelopment"
  }' | jq .
{
  "id": "...",
  "org_id": "...",
  "name": "...",
  "key": "...",
  "budget_cents": 5000000,
  "capitalization_type": "Capex",
  "development_phase": "AppDevelopment",
  "created_at": "...",
  "updated_at": "..."
}

MCP shortcut: Ask your AI assistant: “Create a project called Website Redesign with key WEB” — it calls create_project behind the scenes.

See the Projects & Tickets guide for full project configuration options.

3. Building Your Team

Add members to your project with the right roles. Project membership controls who can see and interact with a project:

curl -s -X POST "$BASE_URL/api/v1/projects/$PROJECT_ID/members" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d "{
    \"user_id\": \"$USER_ID\"
  }" | jq .
{
  "project_id": "...",
  "user_id": "...",
  "created_at": "..."
}

List who is on the project:

curl -s "$BASE_URL/api/v1/projects/$PROJECT_ID/members" \
  -H "Authorization: Bearer $TOKEN" | jq .
[
  {
    "project_id": "...",
    "user_id": "...",
    "created_at": "..."
  }
]

Need to bring someone new into the org first? Send an invite:

curl -s -X POST "$BASE_URL/api/v1/orgs/$ORG_ID/invites" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d "{
    \"email\": \"designer-pm@example.com\",
    \"role\": \"Member\",
    \"created_by\": \"$USER_ID\"
  }" | jq .
{
  "id": "...",
  "invite_code": "...",
  "invite_link": "...",
  "email": "designer-pm@example.com",
  "role": "Member",
  "expires_at": "..."
}

See the Teams, Roles & Permissions guide for the full permission matrix and role descriptions.

4. Managing the Backlog

Create tickets to track work. Every ticket gets a project-scoped number automatically:

curl -s -X POST "$BASE_URL/api/v1/projects/$PROJECT_ID/tickets" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d "{
    \"title\": \"Design homepage wireframes\",
    \"description\": \"Create wireframes for the new homepage layout\",
    \"priority\": \"High\",
    \"reporter_id\": \"$USER_ID\"
  }" | jq .
{
  "id": "...",
  "project_id": "...",
  "ticket_number": "...",
  "title": "Design homepage wireframes",
  "description": "Create wireframes for the new homepage layout",
  "status": "...",
  "priority": "High",
  "reporter_id": "...",
  "created_at": "...",
  "updated_at": "..."
}

Assign a ticket to a team member:

curl -s -X PATCH "$BASE_URL/api/v1/tickets/$TICKET_ID" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d "{
    \"assignee_id\": \"$USER_ID\"
  }" | jq .
{
  "id": "...",
  "project_id": "...",
  "ticket_number": "...",
  "title": "...",
  "status": "...",
  "priority": "...",
  "assignee_id": "...",
  "reporter_id": "...",
  "created_at": "...",
  "updated_at": "..."
}

List the backlog filtered by priority:

curl -s "$BASE_URL/api/v1/projects/$PROJECT_ID/tickets?priority=High&limit=5" \
  -H "Authorization: Bearer $TOKEN" | jq .
{
  "items": [
    {
      "id": "...",
      "project_id": "...",
      "ticket_number": "...",
      "title": "...",
      "status": "...",
      "priority": "High",
      "assignee_id": "...",
      "reporter_id": "...",
      "created_at": "...",
      "updated_at": "..."
    }
  ],
  "next_cursor": "..."
}

MCP shortcut: Ask your AI assistant: “Show me all high-priority tickets in WEB” — it calls search_tickets with the right filters.

See the Projects & Tickets guide for search, filtering, and bulk operations.

5. Organizing with Labels and Tags

Use labels to categorize tickets by type, component, or any dimension that matters to your project:

curl -s -X POST "$BASE_URL/api/v1/orgs/$ORG_ID/labels" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "name": "frontend",
    "color": "#3B82F6"
  }' | jq .
{
  "id": "...",
  "org_id": "...",
  "name": "frontend",
  "color": "#3B82F6",
  "created_at": "...",
  "updated_at": "..."
}

Apply a label to a ticket:

curl -s -X POST "$BASE_URL/api/v1/tickets/$TICKET_ID/labels/$LABEL_ID" \
  -H "Authorization: Bearer $TOKEN" | jq .
[
  {
    "id": "...",
    "org_id": "...",
    "name": "...",
    "color": "...",
    "created_at": "...",
    "updated_at": "..."
  }
]

Use tags for lightweight, key-value grouping (no pre-creation needed):

curl -s -X PUT "$BASE_URL/api/v1/orgs/$ORG_ID/ticket/$TICKET_ID/tags" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "tags": [{"key": "quarter", "value": "Q2"}, {"key": "blocker", "value": "launch"}]
  }' | jq .
[
  {
    "id": "...",
    "entity_type": "...",
    "entity_id": "...",
    "key": "...",
    "value": "...",
    "created_at": "..."
  }
]

MCP shortcut: “Tag ticket WEB-5 as launch-blocker” — calls set_tags.

See the Labels, Tags & Organization guide for the full labeling and tagging workflow.

6. Setting Up Workflows

Define how tickets flow through your process. As a PM, you control the allowed transitions and enforcement level:

curl -s -X POST "$BASE_URL/api/v1/orgs/$ORG_ID/workflows" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "name": "PM Standard Flow",
    "statuses": [
      {"name": "Backlog", "category": "todo"},
      {"name": "Ready", "category": "todo"},
      {"name": "InProgress", "category": "in_progress"},
      {"name": "Review", "category": "in_progress"},
      {"name": "Done", "category": "done"}
    ],
    "transitions": [
      {"from": "Backlog", "to": "Ready"},
      {"from": "Ready", "to": "InProgress"},
      {"from": "InProgress", "to": "Review"},
      {"from": "Review", "to": "Done"},
      {"from": "Review", "to": "InProgress"}
    ],
    "enforcement": "strict"
  }' | jq .
{
  "id": "...",
  "org_id": "...",
  "name": "PM Standard Flow",
  "statuses": [
    {"name": "Backlog", "category": "todo"},
    {"name": "Ready", "category": "todo"},
    {"name": "InProgress", "category": "in_progress"},
    {"name": "Review", "category": "in_progress"},
    {"name": "Done", "category": "done"}
  ],
  "transitions": [
    {"from": "Backlog", "to": "Ready"},
    {"from": "Ready", "to": "InProgress"},
    {"from": "InProgress", "to": "Review"},
    {"from": "Review", "to": "Done"},
    {"from": "Review", "to": "InProgress"}
  ],
  "enforcement": "strict",
  "created_at": "...",
  "updated_at": "..."
}

With strict enforcement, the API rejects any transition not in the allowed list. Use "enforcement": "relaxed" if you want the workflow as guidance rather than a hard rule.

Assign the workflow to your project by updating the project:

curl -s -X PATCH "$BASE_URL/api/v1/projects/$PROJECT_ID" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d "{
    \"workflow_id\": \"$WORKFLOW_ID\"
  }" | jq .
{
  "id": "...",
  "org_id": "...",
  "name": "Website Redesign",
  "key": "WEB",
  "workflow_id": "...",
  "created_at": "...",
  "updated_at": "..."
}

See the Workflows & Statuses guide for enforcement modes, transition rules, and handling rejected transitions.

7. Sprint Planning and Execution

Create sprints to time-box your team’s work. Set a goal so everyone knows what the sprint is about:

curl -s -X POST "$BASE_URL/api/v1/projects/$PROJECT_ID/sprints" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "name": "Sprint 1 — Homepage Launch",
    "goal": "Ship the new homepage design to production",
    "start_date": "2026-04-01",
    "end_date": "2026-04-15"
  }' | jq .
{
  "id": "...",
  "project_id": "...",
  "name": "Sprint 1 — Homepage Launch",
  "goal": "Ship the new homepage design to production",
  "start_date": "2026-04-01",
  "end_date": "2026-04-15",
  "status": "Planned",
  "created_at": "...",
  "updated_at": "..."
}

Start the sprint when the team is aligned:

curl -s -X POST "$BASE_URL/api/v1/sprints/$SPRINT_ID/start" \
  -H "Authorization: Bearer $TOKEN" | jq .
{
  "id": "...",
  "project_id": "...",
  "name": "Sprint 1 — Homepage Launch",
  "goal": "Ship the new homepage design to production",
  "start_date": "2026-04-01",
  "end_date": "2026-04-15",
  "status": "Active",
  "created_at": "...",
  "updated_at": "..."
}

Track progress with the burndown endpoint:

curl -s "$BASE_URL/api/v1/sprints/$SPRINT_ID/burndown" \
  -H "Authorization: Bearer $TOKEN" | jq .
{
  "sprint_id": "...",
  "data": "..."
}

MCP shortcut: “Start sprint 1 in WEB” — calls start_sprint.

See the Sprints & Boards guide and the Running a Sprint playbook for the full sprint lifecycle.

8. Tracking Progress and Status

List tickets in your project to see who is working on what. Filter by status, priority, or assignee:

curl -s "$BASE_URL/api/v1/projects/$PROJECT_ID/tickets?limit=5" \
  -H "Authorization: Bearer $TOKEN" | jq .
{
  "items": [
    {
      "id": "...",
      "project_id": "...",
      "ticket_number": "...",
      "title": "...",
      "status": "...",
      "priority": "...",
      "reporter_id": "...",
      "created_at": "...",
      "updated_at": "..."
    }
  ],
  "next_cursor": "..."
}

Filter by status (?status=InProgress), priority (?priority=High), or assignee (?assignee_id=...) to narrow results.

MCP shortcut: “Give me a summary of project WEB” — calls get_project_summary and returns ticket counts by status and active sprints.

9. Budget and Cost Tracking

With budget and capitalization fields set on your project, track spend as time entries are approved:

curl -s "$BASE_URL/api/v1/reports/capitalization?period=2026-04" \
  -H "Authorization: Bearer $TOKEN" | jq .
{
  "period": "2026-04",
  "projects": []
}

When approved time entries exist with labor rates configured, each project entry includes project_id, project_name, total_hours, total_amount_cents, and an activity breakdown. Compare total_amount_cents against your project’s budget_cents to track utilization.

Add include_budget=true to include budget_cents, spent_cents, budget_remaining_cents, and budget_utilization_pct on each project.

For CSV exports (useful for spreadsheets and ERP import):

curl -s "$BASE_URL/api/v1/reports/capitalization/export?period=2026-04" \
  -H "Authorization: Bearer $TOKEN" -o report.csv

See the Time Tracking & Finance guide for labor rates, approval workflows, and CSV export.

10. Communicating with Comments

Use comments on tickets to keep discussions in context rather than scattered across Slack and email:

curl -s -X POST "$BASE_URL/api/v1/tickets/$TICKET_ID/comments" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d "{
    \"body\": \"Wireframes approved by stakeholders. Moving to development.\",
    \"author_id\": \"$USER_ID\"
  }" | jq .
{
  "id": "...",
  "ticket_id": "...",
  "author_id": "...",
  "body": "Wireframes approved by stakeholders. Moving to development.",
  "created_at": "...",
  "updated_at": "..."
}

List comments on a ticket to review the discussion history:

curl -s "$BASE_URL/api/v1/tickets/$TICKET_ID/comments?limit=10" \
  -H "Authorization: Bearer $TOKEN" | jq .
{
  "items": [
    {
      "id": "...",
      "ticket_id": "...",
      "author_id": "...",
      "body": "...",
      "created_at": "...",
      "updated_at": "..."
    }
  ],
  "next_cursor": "..."
}

MCP shortcut: “Add a comment to WEB-3: Design approved, start coding” — calls add_comment.

11. MCP-First Workflow

The MCP server is the fastest way to manage your project day-to-day. Here are the commands a PM uses most:

ActionMCP ToolWhat it does
Project overviewget_project_summaryTicket counts by status, active sprints
Create a ticketcreate_ticketAdd work to the backlog
Assign workassign_ticketSet the assignee on a ticket
Move a tickettransition_ticketChange status following workflow rules
Start a sprintstart_sprintKick off a planned sprint
Sprint burndownget_sprint_burndownTrack completion progress
Search ticketssearch_ticketsFind tickets by keyword, status, assignee
My ticketsget_my_ticketsSee what is assigned to you
Add a commentadd_commentLeave notes on a ticket
Tag a ticketset_tagsApply ad-hoc tags for grouping

All MCP tools respect the same permissions as the REST API. You need the appropriate role to perform each action.

See the MCP Tools Reference for the full list of tools and their parameters.

12. Day-One Checklist

Here is a step-by-step checklist for setting up your project in Alloy:

  1. Create your organizationPOST /api/v1/orgs
  2. Create a project — Set name, key, and org_id
  3. Configure budget — Update the project with budget_cents, capitalization_type, and development_phase
  4. Set up a workflow — Create a workflow matching your process, assign it to the project
  5. Create labels — Define categories (frontend, backend, design, bug, feature) at the org level
  6. Invite team members — Send invites with appropriate roles
  7. Add project members — Add each person to the project
  8. Create backlog tickets — Break work into tickets with priorities and descriptions
  9. Assign owners — Set an assignee on each ticket
  10. Create your first sprint — Plan a two-week iteration with a goal
  11. Start the sprint — Kick it off when the team is ready
  12. Set up reporting — Configure labor rates for cost tracking

Each step maps to an API call or MCP command described in this guide. For a complete walkthrough, see the Setting Up a New Team playbook.


Learn More: