The Brick & Yield API lets you sync clients, notes, tags, and tasks between Brick & Yield and your CRM or other tools. It powers the official Brick & Yield Zapier integration, and can be used directly by any HTTP client.
The API is organized around REST. All requests and responses use JSON. Every endpoint is scoped to a single agent — an API key can only read and write that agent's own clients and their related records. There is no access to other agents' data.
The API is versioned under /api/v1. Two-way sync is supported: you can push data in with the actions below, and receive real-time events out via webhooks (see Webhooks).
The API uses per-agent API keys. An agent generates a key in the Brick & Yield admin app under Settings → API Keys. The key is shown once at creation time and stored hashed — if it is lost, revoke it and generate a new one.
Pass the key as a bearer token on every request. X-API-Key: <key> is also accepted.
Authorization: Bearer by_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxRequests without a valid, non-revoked key return 401 Unauthorized. Verify a key with the connection test endpoint.
Successful responses include "ok": true alongside the returned resource. Write endpoints return 201 Created; reads and idempotent updates return 200 OK.
Errors return a non-2xx status with a JSON body:
{ "error": "Client not found." }| Field | Type | Description |
|---|---|---|
400 | Bad Request | Missing or invalid fields (body includes validation details). |
401 | Unauthorized | Missing, invalid, or revoked API key. |
404 | Not Found | The referenced client does not exist for this agent. |
500 | Server Error | Unexpected error; safe to retry. |
Create/update and find operations locate an existing client using the following identifiers, in order. The first one that matches wins — this keeps repeated syncs from creating duplicates:
external_id (exact match). Recommended: store your CRM's contact ID so matching survives email changes.Note, tag, and task endpoints accept any of these in the {id} path segment — the Brick & Yield client UUID, the external_id, or the client's email.
Returns the agent and organization the API key belongs to. Used to verify a key.
curl https://api.brickandyield.app/api/v1/me \
-H "Authorization: Bearer by_live_xxx"{
"ok": true,
"agent": { "id": "…", "name": "Jane Agent", "email": "jane@brokerage.com" },
"organization": { "id": "…", "name": "Acme Realty" }
}Create a client, or update the existing one if a match is found (see matching). On update, only the fields you send are changed; omitted fields are left as-is. New clients are created without an app login (the agent can invite them to the client portal later).
| Field | Type | Description |
|---|---|---|
external_id | string | Your CRM's contact ID. Strongly recommended for reliable matching. |
external_source | string | CRM name, e.g. "hubspot", "salesforce". |
first_name | string | Given name. |
last_name | string | Family name. |
full_name | string | Full name. Derived from first/last if omitted. |
email | string | Email address. |
phone | string | Phone number (any format). |
stage | enum | Buyer stage — see Field reference. |
portal_type | enum | buyer · seller · both. |
client_type | enum | See Field reference. |
tags | string[] | string | Tag names to add (array or comma-separated). Additive — never removes tags. |
At least one of full_name, first_name/last_name, email, or phone is required.
curl -X POST https://api.brickandyield.app/api/v1/clients \
-H "Authorization: Bearer by_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"external_id": "crm-123",
"external_source": "hubspot",
"first_name": "Jane",
"last_name": "Doe",
"email": "jane@example.com",
"phone": "(801) 555-1234",
"stage": "new",
"portal_type": "buyer",
"tags": ["Hot Lead", "Investor"]
}'{
"ok": true,
"created": true,
"client": {
"id": "541218ce-9b41-4c1a-ba01-65b2d15a2a09",
"external_id": "crm-123",
"external_source": "hubspot",
"first_name": "Jane",
"last_name": "Doe",
"full_name": "Jane Doe",
"email": "jane@example.com",
"phone": "(801) 555-1234",
"stage": "new",
"portal_type": "buyer",
"client_type": "home_buyer",
"source": "zapier",
"created_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-01T00:00:00.000Z"
}
}Find a single client by external_id, email, or phone (query parameters). At least one is required. Returns "client": null when nothing matches.
curl "https://api.brickandyield.app/api/v1/clients?email=jane@example.com" \
-H "Authorization: Bearer by_live_xxx"{ "ok": true, "client": { "id": "…", "full_name": "Jane Doe", … } }For each of these, {id} may be the Brick & Yield client UUID, the external_id, or the client's email (URL-encode it).
| Field | Type | Description |
|---|---|---|
body | string | Note text (required, up to 5000 chars). |
curl -X POST https://api.brickandyield.app/api/v1/clients/crm-123/notes \
-H "Authorization: Bearer by_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "body": "Called, left a voicemail." }'{ "ok": true, "note": { "id": "…", "body": "Called, left a voicemail.", "created_at": "…", "source": "zapier" } }Adds a tag, creating the org-level tag if it doesn't exist yet. Additive.
| Field | Type | Description |
|---|---|---|
name | string | Tag name (required). |
color | string | Optional hex color, e.g. "#10b981". |
{ "ok": true, "tag": { "id": "…", "name": "Hot Lead", "color": "#10b981" } }| Field | Type | Description |
|---|---|---|
title | string | Task title (required). |
description | string | Optional details. |
due_date | string | Optional, YYYY-MM-DD. |
curl -X POST https://api.brickandyield.app/api/v1/clients/crm-123/tasks \
-H "Authorization: Bearer by_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "title": "Send listing agreement", "description": "Get it signed by Friday.", "due_date": "2026-01-05" }'{ "ok": true, "task": { "id": "…", "title": "Send listing agreement", "description": "Get it signed by Friday.", "due_date": "2026-01-05", "completed": false, "source": "zapier" } }The API delivers real-time events via REST hooks. You subscribe a target URL to an event type; Brick & Yield then POSTs the event payload to that URL whenever it occurs. Events fire only from in-app activity, never from API writes — so a two-way sync will not loop.
| Field | Type | Description |
|---|---|---|
event | enum | One of the event types below. |
target_url | string | HTTPS URL that will receive the POSTed event. |
curl -X POST https://api.brickandyield.app/api/v1/hooks/subscribe \
-H "Authorization: Bearer by_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "event": "client.updated", "target_url": "https://hooks.example.com/abc" }'{ "ok": true, "id": "5b3d483d-…" }Removes a subscription by the id returned from subscribe.
{ "ok": true }Returns up to 3 recent items shaped exactly like the live webhook payload, for building and testing a subscription. Pass ?event= with one of the event types.
curl "https://api.brickandyield.app/api/v1/hooks/sample?event=client.updated" \
-H "Authorization: Bearer by_live_xxx"| Field | Type | Description |
|---|---|---|
client.created | event | A client was created in Brick & Yield. |
client.updated | event | A client was created or edited — fields, stage, or tags. |
client.stage_changed | event | A client's stage changed. |
note.created | event | A note was added to a client. |
task.created | event | A task was created for a client. |
tag.added | event | A tag was added to a client. |
Each event is delivered as a JSON POST body. The shapes are:
{
"event": "client.updated",
"client": {
"id": "541218ce-9b41-4c1a-ba01-65b2d15a2a09",
"external_id": "crm-123",
"external_source": "hubspot",
"first_name": "Jane",
"last_name": "Doe",
"full_name": "Jane Doe",
"email": "jane@example.com",
"phone": "(801) 555-1234",
"stage": "new",
"portal_type": "buyer",
"client_type": "home_buyer",
"tags": ["Hot Lead", "Investor"]
}
}{
"event": "note.created",
"note": { "id": "…", "body": "Called, left a voicemail.", "created_at": "…" },
"client": { "id": "…", "full_name": "Jane Doe", "external_id": "crm-123", "email": "jane@example.com" }
}{
"event": "task.created",
"task": { "id": "…", "title": "Send listing agreement", "description": "…", "due_date": "2026-01-05", "completed": false },
"client": { "id": "…", "full_name": "Jane Doe", "external_id": "crm-123", "email": "jane@example.com" }
}{
"event": "tag.added",
"tag": { "id": "…", "name": "Hot Lead", "color": "#10b981" },
"client": { "id": "…", "full_name": "Jane Doe", "external_id": "crm-123", "email": "jane@example.com" }
}new · active · nurture · touring · under_contract · closed · paused
buyer · seller · both
investor · out_of_state_investor · house_hacker · home_buyer · seller_only