OQL · Entities
Contacts
OQL field reference for contacts. The people in your CRM and their associated company, communication details, and metadata.
Maintained by the OnePageCRM engineering team · Last updated Jul 28, 2026
Contacts are the people in your CRM and their associated company, communication details, and metadata.
Default sort: weight descending. When you omit order_by,
contacts return in Action Stream priority
order (the same
order the OnePageCRM app uses).
Fields
Legend: F filterable, S sortable, A aggregatable, G groupable.
| Field | Type | F | S | A | G | Description |
|---|---|---|---|---|---|---|
id | ID | Y | — | — | — | Contact ID |
first_name | string | Y | Y | — | — | First name |
last_name | string | Y | Y | — | — | Last name |
company_name | string | Y | Y | — | — | Company name (display text) |
company_id | ID | Y | — | — | Y | Linked company record ID |
job_title | string | Y | Y | — | — | Job title |
status | string (output only) | — | — | — | — | Status display name. Filter and sort by status_id instead. |
status_id | string | Y | Y | — | Y | Status system_id (e.g. lead, prospect, customer) |
owner_id | ID | Y | — | — | Y | Owner user ID |
lead_source | string (output only) | — | — | — | — | Lead source display name |
lead_source_id | string | Y | Y | — | Y | Lead source system_id |
tags | string[] | Y | — | — | Y | Tag names |
starred | boolean (virtual) | Y | — | — | — | Starred by the current user |
background | string | — | — | — | — | Background text (select only) |
address | string | Y | — | — | — | Primary street address |
city | string | Y | Y | — | Y | Primary address city |
state | string | Y | Y | — | Y | Primary address state or region |
zip_code | string | Y | — | — | — | Primary address postal code |
country_code | string | Y | Y | — | Y | ISO 3166-1 alpha-2 country code |
address_type | string | Y | — | — | Y | One of work, home, billing, delivery, other |
created_at | time | Y | Y | — | Y | Record creation timestamp |
modified_at | time | Y | Y | — | Y | Last modification timestamp |
last_activity_date | time | Y | Y | — | Y | Most recent activity (note, call, meeting, deal) |
weight | number (virtual) | — | Y | — | — | Action Stream sort weight. Default sort field. |
emails | array | Y | — | — | — | {address, type} objects |
phones | array | Y | — | — | — | {number, type} objects |
urls | array | Y | — | — | — | {url, type} objects |
Notes
- Virtual fields (
status,lead_source) are display labels resolved from their underlying_idfield at query time. You cannot select, filter, or sort by them directly; use the_idfield instead. tagsuses bare-string equality for single-tag membership ({"tags": "VIP"}) andinfor multi-tag overlap ({"tags": {"in": ["VIP", "Hot"]}}). Grouping bytagsgives a per-tag breakdown: each tag is its own bucket, so a contact tagged bothVIPandHotis counted under each.count()per tag is exact; summing an unrelated field double-counts multi-tag contacts.starredis per-user. The value reflects whether the calling user has starred the contact, not whether anyone has.emails,phones,urlsare arrays of objects. Filter using dotted subfields:emails.address,emails.type(work,home,other)phones.number,phones.type(work,mobile,home,direct,fax,other)urls.url,urls.type(website,blog,twitter,linkedin,facebook,instagram,xing,other)
- Lookups:
company(viacompany_id). Pull the linked company record’s fields inline ascompany.<field>— for examplecompany.name,company.city, orcompany.country_code— inselect,where, andorder_by. See Concepts › Lookups. company_namevs thecompanylookup.company_nameis text stored on the contact and is set even when no company record is linked;company.<field>reads the linked record. A contact with acompany_namebut nocompany_idreturnsnullfor everycompany.<field>.- Custom fields are queryable by name as
custom_fields.<name>inselect,where, andorder_by; selectcustom_fields.*(or*) to return all of them. Filterability and sortability depend on the field’s type. Numeric custom fields can also be aggregated ({ "sum": ["custom_fields.<name>"] }), andmin/maxwork on date custom fields.group_byanddistincton custom fields are not supported: group by a top-level field and filter on the custom field inwhereinstead. Usedescribeto discover an account’s custom-field names and types.
Example queries
Open leads owned by me, top of stream:
{
"from": "contacts",
"where": { "owner_id": "ME()", "status_id": "lead" },
"limit": 25
}
Contacts I’ve starred:
{
"from": "contacts",
"where": { "starred": true }
}
Contacts whose linked company is in Ireland, with the company’s city:
{
"from": "contacts",
"select": ["first_name", "last_name", "company_name", "company.city"],
"where": { "company.country_code": "IE" },
"order_by": [{ "company.name": "asc" }]
}
Contacts at an Irish phone number, with no activity in the last 30 days:
{
"from": "contacts",
"where": {
"phones.number": { "like": "+353%" },
"last_activity_date": { "<": { "DAYS_AGO": [30] } }
}
}
Contacts by country:
{
"from": "contacts",
"select": ["country_code", "count()"],
"where": { "country_code": { "is not": null } },
"group_by": ["country_code"]
}