Notes
Polymorphic notes filtered by entity_type + entity_id. Supported types: venue_lead (alias venue), lead, company, contact.
Storage / UI parity
- venue_lead →
notesonly - lead / company / contact →
notesrow plusfollowupsText dual-write so sales timelines still show the text.source_followup_idde-dupes lists. - Responses include
storage:"notes"or"followups", plusentity_type/entity_id. - Until the polymorphic migration runs, company/contact notes return
400namingmigrations/2026_09_18_001_notes_polymorphic.sql.
Quickstart
Base URL (canonical)
https://api.strackerapp.com/v1/
Same gateway also answers under /api/v1 on strackerapp.com. Prefer the api. subdomain. Do not use api.stracker.io (not wired; returns 403).
Environments (keep separate)
| Env | Base | Keys |
|---|---|---|
| Production | https://api.strackerapp.com/v1 | sk_prod_… only |
| Local smoke | http://127.0.0.1:8888/api/v1 | sk_dev_… only |
Never mix prod keys with local, or local keys with prod.
Auth (all endpoints)
Org-scoped Bearer API key. Agent keys act as the agent with reports_to ACL inheritance.
Authorization: Bearer sk_REPLACE
Content-Type: application/json
# Optional alternate header:
# X-Stracker-Api-Key: sk_REPLACE
Response envelope
{
"success": true,
"data": { /* endpoint-specific payload */ }
}
Errors
Failed responses always have success: false and an error object with a stable code and a human-readable message:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "company_name is required"
}
}
| HTTP status | When | What to do |
|---|---|---|
400 | Validation failed (missing required fields, bad enum, migration not applied for company/contact notes, assignee not in org, slot unavailable). | Read error.message; fix the payload. |
401 | Missing or invalid Authorization / X-Stracker-Api-Key. | Check the API key; confirm the header is present. |
403 | Key is valid but lacks permission (e.g. non-admin calling agent admin endpoints), or org scope mismatch. | Use an org-admin key, or confirm the resource belongs to the key's org. |
404 | Resource not found or not visible to this org. | Verify the id and org scoping. |
500 | Unexpected server error. | Retry with backoff; report if persistent. |
Notes
Endpoints at a glance
| Action | Method + Path | Summary |
|---|---|---|
| List notes | GET /notes | List notes for an entity. Required: entity_type + entity_id. |
| Create a note | POST /notes | Create a note. Requires entity_type, entity_id (or lead_id/company_id/contact_id/venue_lead_id), and content. |
| Get a note | GET /notes/{id} | Get a single note by id. Pass entity_type when known. |
| Update a note | PATCH/PUT /notes/{id} | Update a note's content. |
| Delete a note | DELETE /notes/{id} | Delete a note by id. |
GET /notes
List notes for an entity. Required: entity_type + entity_id.
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
entity_type |
string |
yes | venue_lead|lead|company|contact |
entity_id |
integer |
yes | Parent entity id |
limit |
integer |
no | Page size Default: 50. |
offset |
integer |
no | Offset |
Request example
curl -sS "https://api.strackerapp.com/v1/notes?entity_type=lead&entity_id=1" \
-H "Authorization: Bearer sk_REPLACE"
Response 200 OK
{
"success": true,
"data": {
"notes": [
{ "id": 99, "entity_type": "lead", "entity_id": 1, "content": "Follow up Friday", "storage": "notes" }
]
}
}
POST /notes
Create a note. Requires entity_type, entity_id (or lead_id/company_id/contact_id/venue_lead_id), and content.
Body parameters
| Field | Type | Required | Description |
|---|---|---|---|
entity_type |
string |
yes | venue_lead|lead|company|contact |
entity_id |
integer |
no | Parent id (or use typed *_id aliases) |
lead_id |
integer |
no | Alias for entity_id when type=lead |
company_id |
integer |
no | Alias for entity_id when type=company |
contact_id |
integer |
no | Alias for entity_id when type=contact |
venue_lead_id |
integer |
no | Alias for entity_id when type=venue_lead |
content |
string |
yes | Note body |
Request example
curl -sS https://api.strackerapp.com/v1/notes \
-H "Authorization: Bearer sk_REPLACE" \
-H "Content-Type: application/json" \
-d '{"entity_type":"lead","entity_id":1,"content":"API smoke note"}'
Response 201 Created
{
"success": true,
"data": {
"note": { "id": 100, "entity_type": "lead", "entity_id": 1, "content": "API smoke note", "storage": "notes" }
}
}
GET /notes/{id}
Get a single note by id. Pass entity_type when known.
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
id |
integer |
yes | Note id |
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
entity_type |
string |
no | Hint for storage lookup |
Request example
curl -sS "https://api.strackerapp.com/v1/notes/99?entity_type=lead" \
-H "Authorization: Bearer sk_REPLACE"
Response 200 OK
{
"success": true,
"data": {
"note": { "id": 99, "entity_type": "lead", "entity_id": 1, "content": "Follow up Friday", "storage": "notes" }
}
}
PATCH PUT /notes/{id}
Update a note's content.
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
id |
integer |
yes | Note id |
Body parameters
| Field | Type | Required | Description |
|---|---|---|---|
content |
string |
yes | Updated body |
entity_type |
string |
no | Hint for storage lookup |
Request example
curl -sS -X PATCH https://api.strackerapp.com/v1/notes/99 \
-H "Authorization: Bearer sk_REPLACE" \
-H "Content-Type: application/json" \
-d '{"content":"Updated note"}'
Response 200 OK
{
"success": true,
"data": {
"note": { "id": 99, "content": "Updated note", "storage": "notes" }
}
}
DELETE /notes/{id}
Delete a note by id.
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
id |
integer |
yes | Note id |
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
entity_type |
string |
no | Hint for storage lookup |
Request example
curl -sS -X DELETE "https://api.strackerapp.com/v1/notes/99?entity_type=lead" \
-H "Authorization: Bearer sk_REPLACE"
Response 200 OK
{
"success": true,
"data": { "deleted": true }
}