# The REST API: quickstart

Plain HTTPS and JSON at https://app.julius.dealsflow.ai/api/v1, with an API key from your console. Every operation is listed on the reference page and in the OpenAPI description.

The Julius Answer REST API lives at https://app.julius.dealsflow.ai/api/v1. Send an API key from your console as Authorization: Bearer jak_…; requests and answers are JSON; errors come back with a plain-English message. Each key works in one workspace, as the person who made it, with the access you gave it.

## 1. Make a key

In the console, open **Settings, API & AI apps**. Under API keys, give the key a name (where it will be used, like "Zapier" or "Office dashboard"), pick its access and, if you like, when it expires. Copy it right away: it's shown once.
- **Read only** (read): every list and detail, nothing changes.
- **Day-to-day work** (write): also bookings, to-dos, call-backs and notes.
- **Full access** (admin): also the receptionist's setup, team, numbers and connections.

## 2. Your first request curl https://app.julius.dealsflow.ai/api/v1/account \ -H "Authorization: Bearer jak_your_key" { "workspace": {"id": "6cff3f21-44ee-4c93-9181-09ab7b096513", "business": "Joe Plumbing", "timezone": "America/Chicago", "phone_number": "+13125550100"}, "you": {"email": "joe@joeplumbing.com", "role": "owner", "acting_as": "owner"}, "access": {"scopes": ["read", "write", "admin"], "via": "key", "name": "Zapier"} }

## 3. Common requests # Missed calls, newest first curl "https://app.julius.dealsflow.ai/api/v1/calls?show=missed" -H "Authorization: Bearer $KEY" # One call: summary, transcript, the caller and what they asked for curl https://app.julius.dealsflow.ai/api/v1/calls/CALL_ID \ -H "Authorization: Bearer $KEY" # What needs doing: to-dos, bookings to confirm, questions callers asked curl https://app.julius.dealsflow.ai/api/v1/todo -H "Authorization: Bearer $KEY" # Confirm a booking (the caller is emailed) curl -X POST https://app.julius.dealsflow.ai/api/v1/bookings/BOOKING_ID/confirm \ -H "Authorization: Bearer $KEY" # Weekly opening hours (24-hour ranges, the business's time zone) curl -X PUT https://app.julius.dealsflow.ai/api/v1/hours -H "Authorization: Bearer $KEY" \ -H "Content-Type: application/json" \ -d '{"mon": ["08:00-17:00"], "tue": ["08:00-17:00"], "fri": ["08:00-14:00"]}' # Teach the receptionist an answer curl -X PUT https://app.julius.dealsflow.ai/api/v1/answers -H "Authorization: Bearer $KEY" \ -H "Content-Type: application/json" \ -d '{"question": "Do you service tankless water heaters?", "answer": "No, we only work on tank water heaters."}'

Every operation, its inputs and the access it needs are on the [reference page](/docs/reference/). The full machine-readable description is https://app.julius.dealsflow.ai/api/v1/openapi.json (OpenAPI 3.1, no key needed), which tools like Postman, Insomnia and OpenAPI code generators can import.

## Python import os import requests API = "https://app.julius.dealsflow.ai/api/v1" session = requests.Session() session.headers["Authorization"] = f"Bearer {os.environ['JULIUS_KEY']}" def call(method, path, **kwargs): reply = session.request(method, API + path, timeout=30, **kwargs) if reply.status_code >= 400: raise RuntimeError(reply.json()["error"]["message"]) return reply.json() # Every call, page by page calls, before = [], None while True: page = call("GET", "/calls", params={"before": before} if before else {}) calls += page["calls"] before = page["next"] if not before: break print(len(calls), "calls")

## JavaScript const API = "https://app.julius.dealsflow.ai/api/v1"; async function julius(method, path, body) { const reply = await fetch(API + path, { method, headers: { Authorization: `Bearer ${process.env.JULIUS_KEY}`, "Content-Type": "application/json" }, body: body ? JSON.stringify(body) : undefined, }); const data = await reply.json(); if (!reply.ok) throw new Error(data.error.message); return data; } const todo = await julius("GET", "/todo"); for (const booking of todo.bookings_to_confirm) console.log(booking);

Keep keys on your server. The API answers browsers too (open CORS), but a key in a web page can be read by anyone who opens it.

## Errors

Every error has the same shape, with a message you can show to a person: {"error": {"status": 422, "message": "Opening ranges look like 09:00-17:00"}}

Status codes
| Status | Meaning |
|---|---|
| 400 | The body isn't a JSON object, or a partner key left out X-Workspace-ID |
| 401 | No key, a revoked or expired key, or the person left the workspace (the WWW-Authenticate header points to the sign-in metadata) |
| 403 | The key's access or the person's role doesn't allow this operation |
| 404 | That call, contact, booking or other item doesn't exist in this workspace |
| 409 | It can't happen right now (the message says why) |
| 413 | The body is over 256 KB |
| 422 | An input is missing or doesn't look right; the message names it |
| 429 | Too many requests; wait for the Retry-After seconds |
| 500 | Something went wrong on our side; try again in a moment |

## Paging, limits and good habits
- **Calls** come 30 at a time, newest first. Pass the next value as before for the next page; next is null on the last page.
- **Events** come oldest first. Keep the next value and pass it as after to get only what's new. See [the events feed](/docs/events/#events-feed).
- **Rate limits:** 120 requests a minute per key, 4 at the same time per key and 8 per workspace. Questions to the CRM assistant (POST /ask): 30 an hour.
- **Safe to repeat:** PUT and most PATCH requests set a value, so sending one twice does no harm. POST requests that send something (confirming a booking emails the caller) should not be retried blindly.
- **Changes are recorded:** every change made with a key is listed in the console's activity log with the key's name.
- **Download everything:** GET /export (full access) returns every call, contact, booking and message as CSV files in a ZIP.

## Frequently asked questions

### Where do I get an API key?

In the console, open Settings, API & AI apps and make a key under API keys. Owners and admins can make keys. The key is shown once; Julius Answer keeps only a fingerprint of it.

### Is there a sandbox?

Use the free trial workspace: keys work the same way, and requests don't use call minutes. Changes are real, so use a read-only key while you explore.

### What format are dates and times in?

Timestamps are ISO 8601 in UTC. Opening hours, days and booking times are in the business's time zone (get_account returns it).

### Can I use the API with Zapier or Make?

Yes. Use their HTTP or webhook steps with an API key in the Authorization header, and connect a webhook (or poll the events feed) for triggers.

---
Source: https://julius.dealsflow.ai/docs/api/
Updated: 2026-10-20
