AlifOffice |
Sign in Get started free
🔌 Integrations & AI Agents

Give any AI agent full access to your AlifOffice workspace — CRM contacts, deals, projects, tasks, and invoices. Connect via MCP (Claude Desktop & Claude Code), OpenAI function calling, or direct REST API.

Base URL: https://www.alifoffice.com/api/v1  ·  All endpoints return {"ok": true, "data": ...}
🔑 Authentication

Every request needs a Bearer API key and a workspace slug header.

1
Get an API key
Create a free account, then go to Dashboard → Developer → API keys. Or: ao auth login
2
Or get one via the API
POST to /api/v1/auth/login with your email & password.
curl -s -X POST https://www.alifoffice.com/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com","password":"...","workspace":"your-slug"}'

# Response: {"ok":true,"data":{"api_key":"ao_...","active_workspace":"your-slug",...}}

Using the key

curl https://www.alifoffice.com/api/v1/auth/me \
  -H "Authorization: Bearer ao_your_key_here" \
  -H "X-Workspace: your-slug"
🤖 Claude MCP Recommended for Claude

The MCP server exposes all AlifOffice commands as tools that Claude Desktop and Claude Code can call directly. Once configured, just tell Claude what you need — it handles the API calls automatically.

1
Download the MCP server
The server is a single Python 3.9+ file — no extra packages needed.
2
Add to Claude Desktop config
Open ~/Library/Application Support/Claude/claude_desktop_config.json (Mac) or %APPDATA%\Claude\claude_desktop_config.json (Windows).
3
Restart Claude Desktop and start using it
Try: "List all my open CRM deals" or "Create a task in project WEBRD for the login bug, high priority"

claude_desktop_config.json

{
  "mcpServers": {
    "alifoffice": {
      "command": "python3",
      "args": ["/path/to/alifoffice_mcp.py"],
      "env": {
        "AO_API_KEY":   "ao_your_key_here",
        "AO_WORKSPACE": "your-workspace-slug",
        "AO_API_URL":   "https://www.alifoffice.com/api/v1"
      }
    }
  }
}

Claude Code (claude_code_config.json)

{
  "mcpServers": {
    "alifoffice": {
      "command": "python3",
      "args": ["/path/to/alifoffice_mcp.py"],
      "env": {
        "AO_API_KEY":   "ao_your_key_here",
        "AO_WORKSPACE": "your-workspace-slug"
      }
    }
  }
}

Example prompts once connected

"List all my overdue invoices"→ calls ao_invoice_list with status=overdue
"Create a high-priority task in the Website project: Fix checkout bug"→ ao_projects_task_create
"Move the Database migration task to In Review"→ ao_projects_task_update
"Show me all contacts at Acme Corp"→ ao_crm_contact_list with search=Acme
"What's my API quota usage?"→ ao_auth_me
OpenAI Function Calling GPT-4o / GPT-4

Fetch the OpenAI-compatible tool schema from /api/v1/tools and pass it directly to chat.completions.create(). The model decides when to call each tool; you execute the call against our REST API.

import requests, json, openai

AO_KEY  = "ao_your_key_here"
AO_WS   = "your-workspace-slug"
AO_URL  = "https://www.alifoffice.com/api/v1"
HEADERS = {"Authorization": f"Bearer {AO_KEY}", "X-Workspace": AO_WS}

# 1. Fetch tool schema (cache this — it rarely changes)
tools = requests.get(f"{AO_URL}/tools").json()["tools"]

# 2. Chat with tool use
client   = openai.OpenAI()
messages = [{"role": "user", "content": "List all active projects and their open tasks"}]

response = client.chat.completions.create(
    model="gpt-4o", tools=tools, messages=messages
)

# 3. Execute tool calls
for call in (response.choices[0].message.tool_calls or []):
    fn   = call.function.name           # e.g. "ao_projects_list"
    args = json.loads(call.function.arguments)

    # Map tool name → API path
    path = fn.replace("ao_", "").replace("_", "/", 1).replace("_", "-")
    result = requests.get(f"{AO_URL}/{path}", headers=HEADERS, params=args).json()
    print(result)
import OpenAI from "openai";

const AO_KEY     = "ao_your_key_here";
const AO_WS      = "your-workspace-slug";
const AO_URL     = "https://www.alifoffice.com/api/v1";
const AO_HEADERS = { Authorization: `Bearer ${AO_KEY}`, "X-Workspace": AO_WS };

// 1. Fetch tool schema
const { tools } = await fetch(`${AO_URL}/tools`).then(r => r.json());

// 2. Chat with tools
const client   = new OpenAI();
const response = await client.chat.completions.create({
  model: "gpt-4o",
  tools,
  messages: [{ role: "user", content: "Show me unpaid invoices" }],
});

// 3. Execute tool calls
for (const call of response.choices[0].message.tool_calls ?? []) {
  const args = JSON.parse(call.function.arguments);
  const url  = `${AO_URL}/invoice/invoices?` + new URLSearchParams(args);
  const data = await fetch(url, { headers: AO_HEADERS }).then(r => r.json());
  console.log(data);
}
🧠 Anthropic Claude API claude-opus-4 / sonnet

Use the ?format=anthropic query param to get tools in Anthropic's format. Works with all Claude models that support tool use.

import requests, json, anthropic

AO_KEY  = "ao_your_key_here"
AO_WS   = "your-workspace-slug"
AO_URL  = "https://www.alifoffice.com/api/v1"
HEADERS = {"Authorization": f"Bearer {AO_KEY}", "X-Workspace": AO_WS}

# 1. Fetch Anthropic-format tool schema
tools = requests.get(f"{AO_URL}/tools?format=anthropic").json()["tools"]

# 2. Create message with tools
client = anthropic.Anthropic()
message = client.messages.create(
    model="claude-opus-4-6",
    max_tokens=1024,
    tools=tools,
    messages=[{"role": "user", "content": "Create a CRM contact: Jane Smith, jane@acme.com, Acme Corp"}]
)

# 3. Handle tool use blocks
for block in message.content:
    if block.type == "tool_use":
        print(f"Calling: {block.name}")
        print(f"With:    {json.dumps(block.input, indent=2)}")

        # Execute against AlifOffice API
        result = requests.post(
            f"{AO_URL}/crm/contacts",
            headers={**HEADERS, "Content-Type": "application/json"},
            json=block.input
        ).json()
        print(f"Result:  {result['data']['id']}")
import Anthropic from "@anthropic-ai/sdk";

const AO_KEY  = "ao_your_key_here";
const AO_WS   = "your-workspace-slug";
const AO_URL  = "https://www.alifoffice.com/api/v1";

// 1. Fetch Anthropic-format tools
const { tools } = await fetch(`${AO_URL}/tools?format=anthropic`).then(r => r.json());

// 2. Create message
const client  = new Anthropic();
const message = await client.messages.create({
  model: "claude-opus-4-6",
  max_tokens: 1024,
  tools,
  messages: [{ role: "user", content: "List all my active projects" }],
});

// 3. Execute tool calls
for (const block of message.content) {
  if (block.type === "tool_use") {
    const resp = await fetch(`${AO_URL}/projects?` + new URLSearchParams(block.input), {
      headers: { Authorization: `Bearer ${AO_KEY}`, "X-Workspace": AO_WS }
    }).then(r => r.json());
    console.log(resp.data);
  }
}
🌐 Direct REST API Any language

Plain HTTP + JSON. Works with LangChain tools, n8n, Make, Zapier, or any custom integration.

export AO_KEY="ao_your_key_here"
export AO_WS="your-workspace-slug"
export AO="https://www.alifoffice.com/api/v1"

# List projects
curl "$AO/projects" \
  -H "Authorization: Bearer $AO_KEY" \
  -H "X-Workspace: $AO_WS"

# Create a task
curl -X POST "$AO/projects/{project_id}/tasks" \
  -H "Authorization: Bearer $AO_KEY" \
  -H "X-Workspace: $AO_WS" \
  -H "Content-Type: application/json" \
  -d '{"title":"Fix login bug","priority":"high","status":"todo"}'

# List CRM contacts
curl "$AO/crm/contacts?search=acme&limit=20" \
  -H "Authorization: Bearer $AO_KEY" \
  -H "X-Workspace: $AO_WS"
import requests

class AoClient:
    def __init__(self, api_key, workspace, base="https://www.alifoffice.com/api/v1"):
        self.base    = base
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "X-Workspace":   workspace,
            "Content-Type":  "application/json",
        }

    def get(self, path, **params):
        return requests.get(f"{self.base}/{path}", headers=self.headers, params=params).json()

    def post(self, path, **body):
        return requests.post(f"{self.base}/{path}", headers=self.headers, json=body).json()

    def patch(self, path, **body):
        return requests.patch(f"{self.base}/{path}", headers=self.headers, json=body).json()

ao = AoClient("ao_your_key_here", "your-workspace-slug")

# Examples
projects  = ao.get("projects", status="active")
new_task  = ao.post("projects/{id}/tasks", title="Fix bug", priority="high")
contacts  = ao.get("crm/contacts", search="acme corp", limit=10)
deal      = ao.post("crm/deals", title="Enterprise deal", amount=50000, stage="proposal")
📋 Tool Reference

All 19 tools available to AI agents. Full schema at /api/v1/tools.

Auth

ToolEndpointDescription
ao_auth_me GET /auth/me Current user, workspace & quota

CRM

ToolEndpointDescription
ao_crm_contact_list GET /crm/contacts List & search contacts
ao_crm_contact_get GET /crm/contacts/{id} Single contact
ao_crm_contact_create POST /crm/contacts Create contact
ao_crm_contact_update PATCH /crm/contacts/{id} Update contact
ao_crm_deal_list GET /crm/deals List & filter deals
ao_crm_deal_create POST /crm/deals Create deal
ao_crm_deal_update PATCH /crm/deals/{id} Update deal

Projects

ToolEndpointDescription
ao_projects_list GET /projects List projects
ao_projects_create POST /projects Create project
ao_projects_task_list GET /projects/{id}/tasks List tasks
ao_projects_task_create POST /projects/{id}/tasks Create task
ao_projects_task_update PATCH /projects/{id}/tasks/{t} Update task

Invoices

ToolEndpointDescription
ao_invoice_list GET /invoice/invoices List invoices
ao_invoice_get GET /invoice/invoices/{id} Single invoice
ao_invoice_create POST /invoice/invoices Create invoice
ao_invoice_mark_paid POST /invoice/invoices/{id}/mark-paid Mark as paid

Workspace

ToolEndpointDescription
ao_workspace_list GET /workspace List workspaces
ao_workspace_members GET /workspace/{slug}/members List members