Retail Lead Management Read-Only API (3.0)

Download OpenAPI specification:

The RLM v3 API is a read-only JSON API over the same data you see in the Retail Lead Management web app: leads, tasks, companies, contacts, journal entries, attachments and samples.

Compared to the v1 API, v3 offers per-field filtering, sorting, full-text search, pagination, and access to record types v1 does not expose. It writes nothing - every endpoint is a GET. If you need to create leads, use POST /api/{apiKey}/leads on v1.

Machine-readable spec

This page is generated from an OpenAPI 3.0.3 document, served alongside it:

Format URL
JSON /docs/v3/rlm-v3.json
YAML /docs/v3/rlm-v3.yaml

Point a client generator, a request validator, or a coding assistant at either one rather than at this page. enum in them means the API constrains the value; on a response field it is the complete set of values the API will ever send. Values configured per pipeline cannot appear as an enum - see "Which values a field can hold" below for how to read those at runtime.

The v1 spec is published the same way, at /docs/rlm-v1.json.

Requesting access

v3 is off by default. Access must be enabled by RLM support, and three separate things must all be in place before a request will succeed:

  1. v3 access enabled on your organization
  2. v3 access enabled on the specific user the integration will run as
  3. an active user API key issued to that user

Enabling the organization alone is not sufficient, and neither is issuing a key - a user whose own access has not been enabled is rejected even with a valid key belonging to an enabled organization. Contact RLM support with the user account you want the integration to use, and support will enable all three together.

Because access is per-user, treat the credentials as belonging to that user: if they leave, have support issue a new key against a different account rather than sharing one.

Base path

Every endpoint on this page is prefixed /api/v3/, without exception. Read the path printed on each operation as the complete path.

The one documented RLM endpoint that carries no version in its path is v1's POST /api/{apiKey}/leads, and it is not on this page - v3 writes nothing. See the v1 API if you need it.

Authentication

Every request must send all three headers:

Header Value
X-Organization-Api-Key Your organization's API key
X-User-Email The email address of the enabled user
X-User-Api-Key That user's API key

All three must match the same user, and the key must be active. Any mismatch returns 401 Unauthorized.

Note that these are not the same headers v1 uses. v1's X-Api-Key becomes X-Organization-Api-Key here, and v3 adds a per-user secret that v1 has no equivalent of.

What you can see

Results are scoped to what the authenticating user can see in the web app - their visible pipelines, divisions and locations, and for tasks, the task privacy rules. A narrowly scoped user gets fewer records than a broadly scoped one from an identical request. Pick the user whose visibility matches the data set you intend to sync.

v3 draws the same role lines v1 does, from the same six roles:

Role Leads
System Admin, Business Admin, Business Manager, Full View The organization's leads, narrowed to the pipelines, divisions and locations that user may see
Single View Only the leads assigned to them
Assistant Only the leads they created that are still pending and unassigned

Full View is not a manager role, even though it sees everything the three above it see. RLM's manager roles are System Admin, Business Admin and Business Manager; Full View and Single View are salesperson roles. The one place it matters here is list/deleted - see that filter.

Response shape

Every collection endpoint returns the same envelope:

{
  "data": [ ... ],
  "meta": { "matches": 42, "total": 1360 },
  "links": { "self": "...", "next": "..." }
}
  • data - the records for this page
  • meta.matches - how many records matched your query in total
  • meta.total - how many records of this type you can see at all, ignoring your query. Useful as a denominator; it is not the size of the result set.
  • links - pagination URLs, described below

Single-record endpoints return {"data": { ... }}.

Custom fields, and why their values are objects

Leads, tasks, companies, contacts and samples all carry the custom fields configured for them in RLM, on top of the standard keys listed in each schema. Which ones you get depends on the pipeline and the organization, so the key set is data, not something you can hard-code.

A custom field's value is an object, not a scalar. It always has a display key holding the pre-formatted string the web app shows, plus one more key named after the field's type holding the typed value:

{
  "email":        {"display": "a@b.com", "email": "a@b.com"},
  "quote_amount": {"display": null, "currency": null},
  "opt_in":       {"display": "No", "checkbox": false},
  "location":     {"display": "Head Office", "system_id": 2966,
                   "system": "Head Office"}
}

Read display when you want what the user sees, and the typed key when you want to compare, total or convert the value. The CustomFieldValue schema lists every type key and which field types produce it.

Two kinds of field break the pattern and come back as a bare scalar instead: fields RLM marks as locked, and fields whose name collides with a standard indexed column - lead_type, for example, arrives as "lead_type": null rather than an object. Nothing in the payload tells you which form you are looking at, so check the type at runtime. Code that assumes every custom field is a string will break on the first object it meets, and code that assumes every one is an object will break on the first locked field.

This is a real difference from v1, where every custom field is a display string.

To find out which custom fields a pipeline defines, call GET /api/v1/pipeline/{apiKey} on the v1 API - v3 has no field discovery endpoint of its own - and read pipeline_fields[].column_name. v3 keys custom fields by column_name and nothing else. v1 also publishes each field under its api_field_name alias when one is set; v3 ignores that attribute entirely. A field with column_name deal_name and api_field_name deal_name_api appears on a v1 lead under both names and on a v3 lead only as deal_name.

column_name is not the label RLM shows for the field. A field displayed as Lead Source arrives here as source_name, and the label can be renamed without the key changing. The same v1 response carries display_name alongside it, so read both if you need to show a human which field is which

  • and quote the display name, not the key, when asking RLM support about a field.

Which values a field can hold

For fields whose value comes from a list, that list also lives on GET /api/v1/pipeline/{apiKey}:

  • select and multiple_select fields - the permitted values are pipeline_fields[].field_options for that field. Mostly configured per pipeline and editable at any time, so read them rather than hard-coding, and expect them to differ between two pipelines in the same organization. The lead_type and channel_utm fields are the exception: RLM locks their values, so those two are safe to code against. Note that field_options merges the field's current and discontinued values into one array without distinguishing them.
  • state fields - a fixed set of 60 US codes, the same on every pipeline. v1's LeadCreate.state lists them in full.
  • a lead's stage_name - pipeline_statuses[].name, also per pipeline.

This matters most for rlm_filters: filtering on a value that is not in the list is not an error, it simply matches nothing.

Search index keys on list responses

List endpoints are served from the search index, and two of its internal keys survive into the response:

  • _type - on every list record, naming the index it came from.
  • sort - on company and contact lists only. Those default to ordering by lower-cased name, and only all-numeric sort keys get stripped, so a value like [1.0, "acme flooring"] stays put.

Neither is part of the API. Ignore them: they carry no information you cannot get from the documented fields, they are absent from the single-record endpoints, and their contents can change without notice.

Nested paths

Many records are reachable both directly and through a parent - for example GET /api/v3/tasks/{id} and GET /api/v3/leads/{lead_id}/tasks/{id}.

The parent segment is always enforced. On list endpoints it restricts the result set; on single-record endpoints the record must genuinely belong to the parent named in the path, and a mismatch returns 404. The parent itself must also be one of your organization's records, so an unknown or foreign parent id is a 404 too.

This means a nested URL is a relationship assertion: if GET /api/v3/leads/{lead_id}/tasks/{id} returns 200, that task really is on that lead. You can rely on it rather than reading the record back and comparing ids.

(Before 2026-08-13 this was true of journals, attachments and samples but not of nested tasks, leads or contacts, which resolved by {id} alone and ignored the parent. If you built a client against that behaviour - for instance passing a placeholder parent id - it will now receive 404.)

Deleted records

The single-record endpoints for leads, tasks, companies and contacts return soft-deleted records as well as live ones. Check the record's deleted field rather than assuming a 200 means the record is active. The list endpoints exclude deleted records unless you ask for the deleted filter.

Pagination

Collection endpoints return 100 records when you do not ask for a different number. That is a default, not a maximum: page[size] is passed to the search engine as given, and nothing clamps it, so page[size]=400 returns 400 records if that many match.

Request a specific page with page[number] and page[size]:

/api/v3/leads?page[number]=2&page[size]=50

The 10,000-record wall

page[number] × page[size] may not exceed 10,000. Cross it and the request fails with a bare 500 and an empty body - no error envelope, no explanation. It is a hard boundary on how deep you can page and it is not configurable by the caller: at page[size]=100, page 101 does not exist.

Measured: page[size] of 100, 500, 9999 and 10000 all answer 200; page[size]=10001 answers 500, and so does page[number]=200&page[size]=100.

A request past the wall does not fail quickly. It is not rejected up front - it runs, and fails at the end. An in-window request answers in well under a second; a past-the-wall one can take minutes to come back with its 500. Set a client-side timeout accordingly, and do not read a slow response as "still working, give it longer".

Do not retry one unchanged. A past-the-wall request costs far more to fail than an ordinary request costs to succeed, on your side and on RLM's, and a scheduled job that re-issues one on a timer degrades service for your own integration and for other users. Treat a 500 from a paged request as "my window is too big": fix the query before sending it again.

The shape to avoid is a page number that climbs on a schedule until it crosses the wall - a sync that adds a page each run and never re-checks the limit gets there on its own.

Paging deeper is not the way around it. Narrow the query instead, so that each result set is comfortably under 10,000, and move the filter forward rather than the page number:

  1. Pick a window on created_at or updated_at - a few weeks for a busy resource, longer for a quiet one.
  2. Check meta.matches on the first page. If it is near 10,000, halve the window and start again.
  3. Page through that window, then advance the window and repeat.

Starting points that work in practice: 30-day windows on created_at for leads at page[size]=400, which lands around 1,000 matches per window, and 1-day to 5-day windows for contacts and companies, which are higher-volume. Tune from there against your own meta.matches.

Sizing the window this way also keeps you clear of the rate limit. Prefer several modest pages to one very large one: a single huge page is one request, but it is a disproportionately expensive one.

links is always present on a collection response and always carries self. It carries first, prev, next and last as well wherever those pages exist: first and prev are omitted on page 1, next and last on the final page. Follow next until it is absent.

This does not depend on your having asked for a page. A request with no pagination parameters is served as page 1 of size 100, so a query matching more than 100 records comes back with next and last already filled in, and following next walks the whole set. Measured on a 123-record query with no parameters: 100 records, and links.next = ...?page[number]=2&page[size]=100.

Paginate explicitly anyway when you are syncing. Following next from an unparameterised request does work, but the page size is then whatever the default happens to be, and a default that moves shifts every page boundary underneath a resumable sync.

limit is accepted as an alias for page[size].

Filtering

Three independent mechanisms, which combine:

  • {resource}/list/{filter} - a coarse status filter built into the path, e.g. /api/v3/leads/list/closed. Values differ per resource and are documented on each endpoint.
  • query - full-text search across the record.
  • rlm_filters[...] - per-field filtering, described below.

Per-field filters

rlm_filters is a nested query parameter keyed by field name:

?rlm_filters[stage_name]=Sold

Field names are the keys that appear on the records in data, including the custom fields configured on your pipelines. To discover the field names and permitted values for a pipeline, call GET /api/v1/pipeline/{apiKey} on the v1 API - v3 does not expose a field discovery endpoint of its own - and filter on pipeline_fields[].column_name. That is the only name v3 knows a custom field by; the api_field_name alias works on v1 but is ignored here, and because unrecognised field names are dropped silently, filtering on one returns unfiltered results rather than an error.

Pass an array to match any of several values (OR):

?rlm_filters[stage_name][]=Sold&rlm_filters[stage_name][]=Completed

Date and number fields accept range operators - gt, gte, lt, lte and eq:

?rlm_filters[created_at][gte]=2026-08-01&rlm_filters[created_at][lt]=2026-09-01

Any field accepts an emptiness test. empty=true matches records where the field is null, absent or an empty string; empty=false matches records where it has a value:

?rlm_filters[email][empty]=false

Filters on different fields are ANDed together. An unrecognised field name is silently dropped rather than erroring, so a typo returns unfiltered results - check your result counts against meta.matches when adding a filter.

Sorting

rlm_sorting takes a direction and a priority per field, letting you sort by several fields at once - priority orders the sort keys, lowest first:

?rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0

Omit it and each resource applies its own default ordering, documented per endpoint.

Rate limits

v3 is limited to 2 requests per second, measured over a 5 second window. This is deliberately much tighter than v1 because v3 queries are more expensive, and it is enforced both per source IP and per credential set, so spreading requests across machines does not raise the ceiling.

Exceeding it returns 429 Too Many Requests with a Retry-After header giving the seconds to wait. Back off and retry rather than retrying immediately; sustained overage will keep you throttled.

For a one-off bulk extract you are running yourself, a scheduled export is kinder than paging the whole data set. It is not an option for an unattended integration: an export is delivered to the requesting user out of band and the endpoint answers with a queue acknowledgement rather than a file, so a scheduled job has nothing to collect. An automated sync should page an updated_at window instead - see Incremental syncing below - and should not re-read the whole data set on every run.

Incremental syncing

Filter on updated_at and page through the results, oldest first:

/api/v3/leads/list/all
    ?rlm_filters[updated_at][gte]=2026-08-05T14:30:00Z
    &rlm_sorting[updated_at][direction]=asc
    &rlm_sorting[updated_at][priority]=0
    &page[number]=1&page[size]=100

Use list/all rather than the default open so that leads which closed since your last sync are not silently missing from the result.

Bound the window at both ends once you are backfilling. An open-ended gte over a large history matches far more than 10,000 records, and the sync then dies on the wall described under Pagination the moment it reaches page 101. Add an lte, keep meta.matches per window under a few thousand, and advance the window:

/api/v3/leads/list/all
    ?rlm_filters[created_at][gte]=2026-07-01
    &rlm_filters[created_at][lte]=2026-07-31
    &rlm_sorting[created_at][direction]=asc
    &rlm_sorting[created_at][priority]=0
    &page[number]=1&page[size]=400

Steady-state polling of a short window rarely reaches the wall; it is the initial backfill that does.

Leads

A lead is a sales opportunity moving through a pipeline. Leads carry the custom fields configured for their pipeline as well as the standard ones, so the exact key set varies between organizations.

List leads

Returns open leads by default, most recently updated first. Use /api/v3/leads/list/{filter} to select a different set.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

limit
integer
Example: limit=100

Alias for page[size]. Defaults to 100. Supplying this alone caps the result set but does not produce pagination links.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

List leads by status

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
filter
required
string
Enum: "open" "closed" "all" "deleted"
Example: all
  • open - leads still moving through the pipeline
  • closed - leads in a closed status
  • all - open and closed
  • deleted - soft-deleted leads. Only RLM's three manager roles - System Admin, Business Admin, Business Manager - see the whole organization's; everyone else sees only their own. This includes Full View, which is a salesperson role and gets just its own deleted leads here, despite seeing the whole organization under every other filter. See "What you can see".

An unrecognised value falls back to open.

query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

limit
integer
Example: limit=100

Alias for page[size]. Defaults to 100. Supplying this alone caps the result set but does not produce pagination links.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Queue an export of all leads

Queues a spreadsheet export of all open leads and returns immediately. The file is delivered to the authenticating user out of band once generated - it is not returned in the response body.

This is the same operation as /api/v3/leads/list/{filter}/export with {filter} set to open, which is the default when the segment is absent.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

rlm_fields
Array of strings

Which columns to include in the exported spreadsheet, and in what order. Defaults to the standard column set for the record type.

This selects and orders; it cannot add. The export already has a column set - your organization's configured fields for the record type, plus the fixed columns that type's spreadsheet always carries. This parameter narrows that set to the names you list and reorders it to match the order you list them in. A name that is not already a column of yours contributes nothing; it does not create one.

The names are the response property names of the matching list endpoint - taskType, stage_name, created_at - plus the column names of your organization's custom fields. Read one page of the list endpoint to discover them.

Nothing validates this parameter, and no error tells you it was wrong. An unrecognised name is ignored rather than refused; if none of the names you send matches a column, the selection is empty rather than the request failing. Omitting the parameter and sending it empty are the same thing: both give the full default set.

Because the export is queued rather than rendered - the 200 says RLM accepted the job, not that a file exists - a mistake here surfaces in the delivered spreadsheet, not in this response. Verify against the file.

Responses

Response samples

Content type
application/json
{
  • "queued": true
}

Queue a lead export

Queues a spreadsheet export of the leads matching this request and returns immediately. The file is delivered to the authenticating user out of band once generated - it is not returned in the response body.

Accepts the same filtering, search and sorting parameters as the corresponding list endpoint, so you can export exactly the set you would otherwise page through. Use all as the {filter} to export everything.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
filter
required
string
Enum: "open" "closed" "all" "deleted"
Example: all
query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

rlm_fields
Array of strings

Which columns to include in the exported spreadsheet, and in what order. Defaults to the standard column set for the record type.

This selects and orders; it cannot add. The export already has a column set - your organization's configured fields for the record type, plus the fixed columns that type's spreadsheet always carries. This parameter narrows that set to the names you list and reorders it to match the order you list them in. A name that is not already a column of yours contributes nothing; it does not create one.

The names are the response property names of the matching list endpoint - taskType, stage_name, created_at - plus the column names of your organization's custom fields. Read one page of the list endpoint to discover them.

Nothing validates this parameter, and no error tells you it was wrong. An unrecognised name is ignored rather than refused; if none of the names you send matches a column, the selection is empty rather than the request failing. Omitting the parameter and sending it empty are the same thing: both give the full default set.

Because the export is queued rather than rendered - the 200 says RLM accepted the job, not that a file exists - a mistake here surfaces in the delivered spreadsheet, not in this response. Verify against the file.

Responses

Response samples

Content type
application/json
{
  • "queued": true
}

Get a lead

Returns one lead, including soft-deleted ones. The payload carries the same keys as an entry in the list response - this one is rendered from the record itself rather than the search index, but nothing is added or left out because of that.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a lead's tasks

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
lead_id
required
integer
Example: 1234567

The RLM lead id.

query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a task through its lead

Returns the task with the given {id}.

The task must belong to the lead named by {lead_id}; if it does not, or if that lead is not one of your organization's, the response is 404. A 200 here is therefore proof of the relationship.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
lead_id
required
integer
Example: 1234567

The RLM lead id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a lead's samples

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
lead_id
required
integer
Example: 1234567

The RLM lead id.

query Parameters
page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a sample through its lead

Returns the sample with the given {id}, restricted to samples on the lead identified by {lead_id}. Unlike the nested task and lead lookups, this one does honour the parent segment: a sample belonging to a different lead returns 404.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
lead_id
required
integer
Example: 1234567

The RLM lead id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a lead's journal entries

Returns the lead's activity history. Entries are enriched with the display names of the related category, task type and users, alongside their ids. That enrichment happens only here - fetching a single entry by id returns the ids without the names.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
lead_id
required
integer
Example: 1234567

The RLM lead id.

query Parameters
description
string

Free-text search across journal entry text. Note that this parameter is called description but the field it searches is note - there is no description key on a journal entry.

sort_by
string

A relevance hint. It does not impose an order on the response, despite the name - treat it as advisory and do not build on it.

Journal entries always come back the same way: pinned entries first, then by the search engine's relevance score, descending. sort_by does not replace that. It is passed to the search engine as a boost on the named field, which can only move an entry by changing its score - and how much that moves anything, or whether it moves anything at all, depends on the scores already in play. A field name here is not a guarantee of ordering.

The value is one field name, not a list. A leading - weights the boost twice as heavily; it does not mean descending.

If you need a specific order, sort data client-side. No parameter on this endpoint will do it for you: journals and attachments are the two v3 collections that do not accept rlm_sorting.

The web app's journal screens do sort by column, which is why this parameter reads as though it should. They reach the same finder by a different route that applies a real database ordering. The API does not use that route.

journal_category_id
Array of integers

Restrict to one or more journal categories, by id.

No endpoint publishes the id list, so read the ids off the entries themselves: an entry that has a category carries journal_category_id beside a human-readable journal_category. Page through this collection unfiltered once and collect the pairs you find. An uncategorised entry carries neither, so skip those rather than treating them as a category.

That gives you the categories in use, not the full set - a category no entry has ever been given cannot be discovered this way, and there is no request that will list it. Cache what you harvest; the categories are shared reference data rather than per-account configuration, so the mapping does not vary between organizations and does not change often.

An id that matches nothing filters everything out and is not an error.

created_by_id
Array of integers

Restrict to entries created by one or more users, by user id.

v3 has no user directory endpoint. Discover ids the same way as for journal_category_id: an entry with a known author carries created_by_id beside that person's display name in created_by, and the same pairing holds for assigned_to_id and assigned_to. Harvesting those pairs is the only route from a person's name to their id.

The limits are worth stating plainly. You only learn about users who appear in entries you can already see, so this will not enumerate an organization's users, and a user who has written nothing is undiscoverable. Names are display names and are not unique - two people with the same name are two ids, and nothing here disambiguates them.

An id belonging to another organization returns no entries rather than an error, so an empty result does not confirm an id is valid.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a journal entry

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
lead_id
required
integer
Example: 1234567

The RLM lead id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a lead's attachments

Returns attachment metadata and download links. This endpoint is not paginated - it returns every attachment on the record.

For organizations with a BMS integration active, an additional edocs key lists electronic documents held in the connected system. Those entries look like attachments but their links are session-authenticated RLM URLs, not direct file links - read the Edoc schema before planning to fetch them.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
lead_id
required
integer
Example: 1234567

The RLM lead id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "edocs": [
    ]
}

Get an attachment

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
lead_id
required
integer
Example: 1234567

The RLM lead id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a company's leads

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
company_id
required
integer
Example: 1234567

The RLM company id.

query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a lead through its company

Returns the lead with the given {id}.

The lead must belong to the company named by {company_id}; if it does not, or if that company is not one of your organization's, the response is 404. A 200 here is therefore proof of the relationship.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
company_id
required
integer
Example: 1234567

The RLM company id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a contact's leads

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
contact_id
required
integer
Example: 1234567

The RLM contact id.

query Parameters
page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a lead through its contact

Returns the lead with the given {id}.

The lead must belong to the contact named by {contact_id}; if it does not, or if that contact is not one of your organization's, the response is 404. A 200 here is therefore proof of the relationship.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
contact_id
required
integer
Example: 1234567

The RLM contact id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Tasks

Scheduled work attached to a lead, company or contact. Task visibility additionally respects task privacy, so a restricted user sees fewer tasks than they see leads.

List a lead's tasks

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
lead_id
required
integer
Example: 1234567

The RLM lead id.

query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a task through its lead

Returns the task with the given {id}.

The task must belong to the lead named by {lead_id}; if it does not, or if that lead is not one of your organization's, the response is 404. A 200 here is therefore proof of the relationship.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
lead_id
required
integer
Example: 1234567

The RLM lead id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List tasks

Returns incomplete tasks by default, most recently created first. Respects task privacy - private tasks belonging to other users are excluded.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

limit
integer
Example: limit=100

Alias for page[size]. Defaults to 100. Supplying this alone caps the result set but does not produce pagination links.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

List tasks by status

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
filter
required
string
Enum: "incomplete" "completed" "deleted" "all"
Example: incomplete
  • incomplete - not yet completed
  • completed - completed
  • deleted - soft-deleted
  • all - no status restriction

An unrecognised value falls back to all. Note this differs from leads, where the fallback is open.

query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

limit
integer
Example: limit=100

Alias for page[size]. Defaults to 100. Supplying this alone caps the result set but does not produce pagination links.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Queue an export of all tasks

Queues a spreadsheet export of all tasks and returns immediately. The file is delivered to the authenticating user out of band once generated - it is not returned in the response body.

This is the same operation as /api/v3/tasks/list/{filter}/export with {filter} set to all, which is the default when the segment is absent.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

rlm_fields
Array of strings

Which columns to include in the exported spreadsheet, and in what order. Defaults to the standard column set for the record type.

This selects and orders; it cannot add. The export already has a column set - your organization's configured fields for the record type, plus the fixed columns that type's spreadsheet always carries. This parameter narrows that set to the names you list and reorders it to match the order you list them in. A name that is not already a column of yours contributes nothing; it does not create one.

The names are the response property names of the matching list endpoint - taskType, stage_name, created_at - plus the column names of your organization's custom fields. Read one page of the list endpoint to discover them.

Nothing validates this parameter, and no error tells you it was wrong. An unrecognised name is ignored rather than refused; if none of the names you send matches a column, the selection is empty rather than the request failing. Omitting the parameter and sending it empty are the same thing: both give the full default set.

Because the export is queued rather than rendered - the 200 says RLM accepted the job, not that a file exists - a mistake here surfaces in the delivered spreadsheet, not in this response. Verify against the file.

Responses

Response samples

Content type
application/json
{
  • "queued": true
}

Queue a task export

Queues a spreadsheet export of the matching tasks. See /api/v3/leads/list/{filter}/export for how exports are delivered.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
filter
required
string
Enum: "incomplete" "completed" "deleted" "all"
Example: all
query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

rlm_fields
Array of strings

Which columns to include in the exported spreadsheet, and in what order. Defaults to the standard column set for the record type.

This selects and orders; it cannot add. The export already has a column set - your organization's configured fields for the record type, plus the fixed columns that type's spreadsheet always carries. This parameter narrows that set to the names you list and reorders it to match the order you list them in. A name that is not already a column of yours contributes nothing; it does not create one.

The names are the response property names of the matching list endpoint - taskType, stage_name, created_at - plus the column names of your organization's custom fields. Read one page of the list endpoint to discover them.

Nothing validates this parameter, and no error tells you it was wrong. An unrecognised name is ignored rather than refused; if none of the names you send matches a column, the selection is empty rather than the request failing. Omitting the parameter and sending it empty are the same thing: both give the full default set.

Because the export is queued rather than rendered - the 200 says RLM accepted the job, not that a file exists - a mistake here surfaces in the delivered spreadsheet, not in this response. Verify against the file.

Responses

Response samples

Content type
application/json
{
  • "queued": true
}

Get a task

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a task's journal entries

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
task_id
required
integer
Example: 1234567

The RLM task id.

query Parameters
description
string

Free-text search across journal entry text. Note that this parameter is called description but the field it searches is note - there is no description key on a journal entry.

sort_by
string

A relevance hint. It does not impose an order on the response, despite the name - treat it as advisory and do not build on it.

Journal entries always come back the same way: pinned entries first, then by the search engine's relevance score, descending. sort_by does not replace that. It is passed to the search engine as a boost on the named field, which can only move an entry by changing its score - and how much that moves anything, or whether it moves anything at all, depends on the scores already in play. A field name here is not a guarantee of ordering.

The value is one field name, not a list. A leading - weights the boost twice as heavily; it does not mean descending.

If you need a specific order, sort data client-side. No parameter on this endpoint will do it for you: journals and attachments are the two v3 collections that do not accept rlm_sorting.

The web app's journal screens do sort by column, which is why this parameter reads as though it should. They reach the same finder by a different route that applies a real database ordering. The API does not use that route.

journal_category_id
Array of integers

Restrict to one or more journal categories, by id.

No endpoint publishes the id list, so read the ids off the entries themselves: an entry that has a category carries journal_category_id beside a human-readable journal_category. Page through this collection unfiltered once and collect the pairs you find. An uncategorised entry carries neither, so skip those rather than treating them as a category.

That gives you the categories in use, not the full set - a category no entry has ever been given cannot be discovered this way, and there is no request that will list it. Cache what you harvest; the categories are shared reference data rather than per-account configuration, so the mapping does not vary between organizations and does not change often.

An id that matches nothing filters everything out and is not an error.

created_by_id
Array of integers

Restrict to entries created by one or more users, by user id.

v3 has no user directory endpoint. Discover ids the same way as for journal_category_id: an entry with a known author carries created_by_id beside that person's display name in created_by, and the same pairing holds for assigned_to_id and assigned_to. Harvesting those pairs is the only route from a person's name to their id.

The limits are worth stating plainly. You only learn about users who appear in entries you can already see, so this will not enumerate an organization's users, and a user who has written nothing is undiscoverable. Names are display names and are not unique - two people with the same name are two ids, and nothing here disambiguates them.

An id belonging to another organization returns no entries rather than an error, so an empty result does not confirm an id is valid.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a task's journal entry

Returns the journal entry with the given {id}, restricted to entries on the task identified by {task_id}. An entry belonging to a different record returns 404.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
task_id
required
integer
Example: 1234567

The RLM task id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a task's attachments

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
task_id
required
integer
Example: 1234567

The RLM task id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "edocs": [
    ]
}

Get a task's attachment

Returns the attachment with the given {id}, restricted to attachments on the task identified by {task_id}. An attachment belonging to a different record returns 404.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
task_id
required
integer
Example: 1234567

The RLM task id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a company's tasks

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
company_id
required
integer
Example: 1234567

The RLM company id.

query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a task through its company

Returns the task with the given {id}.

The task must belong to the company named by {company_id}; if it does not, or if that company is not one of your organization's, the response is 404. A 200 here is therefore proof of the relationship.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
company_id
required
integer
Example: 1234567

The RLM company id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a contact's tasks

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
contact_id
required
integer
Example: 1234567

The RLM contact id.

query Parameters
page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a task through its contact

Returns the task with the given {id}.

The task must belong to the contact named by {contact_id}; if it does not, or if that contact is not one of your organization's, the response is 404. A 200 here is therefore proof of the relationship.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
contact_id
required
integer
Example: 1234567

The RLM contact id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Companies

Companies are part of the Customer Management Module. On accounts without that module every company endpoint - list and single-record alike - answers 403.

List companies

Returns companies in name order.

Companies are part of the Customer Management Module. Without it the request is refused outright with 403 - you do not get an empty list, so treat a 403 here as "not licensed" rather than "no companies".

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

limit
integer
Example: limit=100

Alias for page[size]. Defaults to 100. Supplying this alone caps the result set but does not produce pagination links.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

List companies by status

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
filter
required
string
Enum: "all" "deleted"
Example: all
  • all - active records
  • deleted - soft-deleted records

An unrecognised value falls back to all.

query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

limit
integer
Example: limit=100

Alias for page[size]. Defaults to 100. Supplying this alone caps the result set but does not produce pagination links.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Queue an export of all companies

Queues a spreadsheet export of all companies and returns immediately. The file is delivered to the authenticating user out of band once generated - it is not returned in the response body.

This is the same operation as /api/v3/companies/list/{filter}/export with {filter} set to all, which is the default when the segment is absent.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

rlm_fields
Array of strings

Which columns to include in the exported spreadsheet, and in what order. Defaults to the standard column set for the record type.

This selects and orders; it cannot add. The export already has a column set - your organization's configured fields for the record type, plus the fixed columns that type's spreadsheet always carries. This parameter narrows that set to the names you list and reorders it to match the order you list them in. A name that is not already a column of yours contributes nothing; it does not create one.

The names are the response property names of the matching list endpoint - taskType, stage_name, created_at - plus the column names of your organization's custom fields. Read one page of the list endpoint to discover them.

Nothing validates this parameter, and no error tells you it was wrong. An unrecognised name is ignored rather than refused; if none of the names you send matches a column, the selection is empty rather than the request failing. Omitting the parameter and sending it empty are the same thing: both give the full default set.

Because the export is queued rather than rendered - the 200 says RLM accepted the job, not that a file exists - a mistake here surfaces in the delivered spreadsheet, not in this response. Verify against the file.

Responses

Response samples

Content type
application/json
{
  • "queued": true
}

Queue a company export

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
filter
required
string
Enum: "all" "deleted"
Example: all
  • all - active records
  • deleted - soft-deleted records

An unrecognised value falls back to all.

query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

rlm_fields
Array of strings

Which columns to include in the exported spreadsheet, and in what order. Defaults to the standard column set for the record type.

This selects and orders; it cannot add. The export already has a column set - your organization's configured fields for the record type, plus the fixed columns that type's spreadsheet always carries. This parameter narrows that set to the names you list and reorders it to match the order you list them in. A name that is not already a column of yours contributes nothing; it does not create one.

The names are the response property names of the matching list endpoint - taskType, stage_name, created_at - plus the column names of your organization's custom fields. Read one page of the list endpoint to discover them.

Nothing validates this parameter, and no error tells you it was wrong. An unrecognised name is ignored rather than refused; if none of the names you send matches a column, the selection is empty rather than the request failing. Omitting the parameter and sending it empty are the same thing: both give the full default set.

Because the export is queued rather than rendered - the 200 says RLM accepted the job, not that a file exists - a mistake here surfaces in the delivered spreadsheet, not in this response. Verify against the file.

Responses

Response samples

Content type
application/json
{
  • "queued": true
}

Get a company

Requires the Customer Management Module. Accounts without it get a 403 with a JSON error body, like every other error on v3.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a company's leads

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
company_id
required
integer
Example: 1234567

The RLM company id.

query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a lead through its company

Returns the lead with the given {id}.

The lead must belong to the company named by {company_id}; if it does not, or if that company is not one of your organization's, the response is 404. A 200 here is therefore proof of the relationship.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
company_id
required
integer
Example: 1234567

The RLM company id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a company's tasks

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
company_id
required
integer
Example: 1234567

The RLM company id.

query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a task through its company

Returns the task with the given {id}.

The task must belong to the company named by {company_id}; if it does not, or if that company is not one of your organization's, the response is 404. A 200 here is therefore proof of the relationship.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
company_id
required
integer
Example: 1234567

The RLM company id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a company's contacts

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
company_id
required
integer
Example: 1234567

The RLM company id.

query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

match_fields
Array of strings

Which fields query searches. Defaults to name. Accepts an array; it has no effect unless query is also supplied.

The accepted names are contact search index fields, the same set rlm_sorting draws on, so the same discovery path applies: every property of the contacts this endpoint returns is a valid name. Two are present on every account - name and company_names - and the rest depend on which fields the account has configured. A configured field is addressed through its display sub-key, as <column_name>.display; RLM's own contact search sends first_name.display, last_name.display and email.display alongside name, and those exist wherever the account has those fields.

A name the index does not carry contributes no matches rather than an error. The failure mode is therefore an empty result set that looks like "no such contact", not a 400 - so if a search returns nothing unexpectedly, check these names before concluding the data is absent. Sending only unrecognised names searches nothing and matches nothing.

page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a contact through its company

Returns the contact with the given {id}.

The contact must be associated with the company named by {company_id}; if it is not, or if that company is not one of your organization's, the response is 404. A 200 here is therefore proof of the relationship.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
company_id
required
integer
Example: 1234567

The RLM company id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a company's journal entries

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
company_id
required
integer
Example: 1234567

The RLM company id.

query Parameters
description
string

Free-text search across journal entry text. Note that this parameter is called description but the field it searches is note - there is no description key on a journal entry.

sort_by
string

A relevance hint. It does not impose an order on the response, despite the name - treat it as advisory and do not build on it.

Journal entries always come back the same way: pinned entries first, then by the search engine's relevance score, descending. sort_by does not replace that. It is passed to the search engine as a boost on the named field, which can only move an entry by changing its score - and how much that moves anything, or whether it moves anything at all, depends on the scores already in play. A field name here is not a guarantee of ordering.

The value is one field name, not a list. A leading - weights the boost twice as heavily; it does not mean descending.

If you need a specific order, sort data client-side. No parameter on this endpoint will do it for you: journals and attachments are the two v3 collections that do not accept rlm_sorting.

The web app's journal screens do sort by column, which is why this parameter reads as though it should. They reach the same finder by a different route that applies a real database ordering. The API does not use that route.

journal_category_id
Array of integers

Restrict to one or more journal categories, by id.

No endpoint publishes the id list, so read the ids off the entries themselves: an entry that has a category carries journal_category_id beside a human-readable journal_category. Page through this collection unfiltered once and collect the pairs you find. An uncategorised entry carries neither, so skip those rather than treating them as a category.

That gives you the categories in use, not the full set - a category no entry has ever been given cannot be discovered this way, and there is no request that will list it. Cache what you harvest; the categories are shared reference data rather than per-account configuration, so the mapping does not vary between organizations and does not change often.

An id that matches nothing filters everything out and is not an error.

created_by_id
Array of integers

Restrict to entries created by one or more users, by user id.

v3 has no user directory endpoint. Discover ids the same way as for journal_category_id: an entry with a known author carries created_by_id beside that person's display name in created_by, and the same pairing holds for assigned_to_id and assigned_to. Harvesting those pairs is the only route from a person's name to their id.

The limits are worth stating plainly. You only learn about users who appear in entries you can already see, so this will not enumerate an organization's users, and a user who has written nothing is undiscoverable. Names are display names and are not unique - two people with the same name are two ids, and nothing here disambiguates them.

An id belonging to another organization returns no entries rather than an error, so an empty result does not confirm an id is valid.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a company's journal entry

Returns the journal entry with the given {id}, restricted to entries on the company identified by {company_id}. An entry belonging to a different record returns 404.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
company_id
required
integer
Example: 1234567

The RLM company id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a company's attachments

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
company_id
required
integer
Example: 1234567

The RLM company id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "edocs": [
    ]
}

Get a company's attachment

Returns the attachment with the given {id}, restricted to attachments on the company identified by {company_id}. An attachment belonging to a different record returns 404.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
company_id
required
integer
Example: 1234567

The RLM company id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Contacts

People, optionally associated with a company. Contacts are also part of the Customer Management Module, with the same 403 on accounts that do not have it.

List a company's contacts

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
company_id
required
integer
Example: 1234567

The RLM company id.

query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

match_fields
Array of strings

Which fields query searches. Defaults to name. Accepts an array; it has no effect unless query is also supplied.

The accepted names are contact search index fields, the same set rlm_sorting draws on, so the same discovery path applies: every property of the contacts this endpoint returns is a valid name. Two are present on every account - name and company_names - and the rest depend on which fields the account has configured. A configured field is addressed through its display sub-key, as <column_name>.display; RLM's own contact search sends first_name.display, last_name.display and email.display alongside name, and those exist wherever the account has those fields.

A name the index does not carry contributes no matches rather than an error. The failure mode is therefore an empty result set that looks like "no such contact", not a 400 - so if a search returns nothing unexpectedly, check these names before concluding the data is absent. Sending only unrecognised names searches nothing and matches nothing.

page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a contact through its company

Returns the contact with the given {id}.

The contact must be associated with the company named by {company_id}; if it is not, or if that company is not one of your organization's, the response is 404. A 200 here is therefore proof of the relationship.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
company_id
required
integer
Example: 1234567

The RLM company id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List contacts

Returns contacts in last-name, first-name order.

Contacts are part of the Customer Management Module. Without it the request is refused outright with 403 - you do not get an empty list, so treat a 403 here as "not licensed" rather than "no contacts".

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

match_fields
Array of strings

Which fields query searches. Defaults to name. Accepts an array; it has no effect unless query is also supplied.

The accepted names are contact search index fields, the same set rlm_sorting draws on, so the same discovery path applies: every property of the contacts this endpoint returns is a valid name. Two are present on every account - name and company_names - and the rest depend on which fields the account has configured. A configured field is addressed through its display sub-key, as <column_name>.display; RLM's own contact search sends first_name.display, last_name.display and email.display alongside name, and those exist wherever the account has those fields.

A name the index does not carry contributes no matches rather than an error. The failure mode is therefore an empty result set that looks like "no such contact", not a 400 - so if a search returns nothing unexpectedly, check these names before concluding the data is absent. Sending only unrecognised names searches nothing and matches nothing.

page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

limit
integer
Example: limit=100

Alias for page[size]. Defaults to 100. Supplying this alone caps the result set but does not produce pagination links.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

List contacts by status

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
filter
required
string
Enum: "all" "deleted"
Example: all
  • all - active records
  • deleted - soft-deleted records

An unrecognised value falls back to all.

query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

match_fields
Array of strings

Which fields query searches. Defaults to name. Accepts an array; it has no effect unless query is also supplied.

The accepted names are contact search index fields, the same set rlm_sorting draws on, so the same discovery path applies: every property of the contacts this endpoint returns is a valid name. Two are present on every account - name and company_names - and the rest depend on which fields the account has configured. A configured field is addressed through its display sub-key, as <column_name>.display; RLM's own contact search sends first_name.display, last_name.display and email.display alongside name, and those exist wherever the account has those fields.

A name the index does not carry contributes no matches rather than an error. The failure mode is therefore an empty result set that looks like "no such contact", not a 400 - so if a search returns nothing unexpectedly, check these names before concluding the data is absent. Sending only unrecognised names searches nothing and matches nothing.

page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

limit
integer
Example: limit=100

Alias for page[size]. Defaults to 100. Supplying this alone caps the result set but does not produce pagination links.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Queue an export of all contacts

Queues a spreadsheet export of all contacts and returns immediately. The file is delivered to the authenticating user out of band once generated - it is not returned in the response body.

This is the same operation as /api/v3/contacts/list/{filter}/export with {filter} set to all, which is the default when the segment is absent.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

match_fields
Array of strings

Which fields query searches. Defaults to name. Accepts an array; it has no effect unless query is also supplied.

The accepted names are contact search index fields, the same set rlm_sorting draws on, so the same discovery path applies: every property of the contacts this endpoint returns is a valid name. Two are present on every account - name and company_names - and the rest depend on which fields the account has configured. A configured field is addressed through its display sub-key, as <column_name>.display; RLM's own contact search sends first_name.display, last_name.display and email.display alongside name, and those exist wherever the account has those fields.

A name the index does not carry contributes no matches rather than an error. The failure mode is therefore an empty result set that looks like "no such contact", not a 400 - so if a search returns nothing unexpectedly, check these names before concluding the data is absent. Sending only unrecognised names searches nothing and matches nothing.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

rlm_fields
Array of strings

Which columns to include in the exported spreadsheet, and in what order. Defaults to the standard column set for the record type.

This selects and orders; it cannot add. The export already has a column set - your organization's configured fields for the record type, plus the fixed columns that type's spreadsheet always carries. This parameter narrows that set to the names you list and reorders it to match the order you list them in. A name that is not already a column of yours contributes nothing; it does not create one.

The names are the response property names of the matching list endpoint - taskType, stage_name, created_at - plus the column names of your organization's custom fields. Read one page of the list endpoint to discover them.

Nothing validates this parameter, and no error tells you it was wrong. An unrecognised name is ignored rather than refused; if none of the names you send matches a column, the selection is empty rather than the request failing. Omitting the parameter and sending it empty are the same thing: both give the full default set.

Because the export is queued rather than rendered - the 200 says RLM accepted the job, not that a file exists - a mistake here surfaces in the delivered spreadsheet, not in this response. Verify against the file.

Responses

Response samples

Content type
application/json
{
  • "queued": true
}

Queue a contact export

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
filter
required
string
Enum: "all" "deleted"
Example: all
  • all - active records
  • deleted - soft-deleted records

An unrecognised value falls back to all.

query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

match_fields
Array of strings

Which fields query searches. Defaults to name. Accepts an array; it has no effect unless query is also supplied.

The accepted names are contact search index fields, the same set rlm_sorting draws on, so the same discovery path applies: every property of the contacts this endpoint returns is a valid name. Two are present on every account - name and company_names - and the rest depend on which fields the account has configured. A configured field is addressed through its display sub-key, as <column_name>.display; RLM's own contact search sends first_name.display, last_name.display and email.display alongside name, and those exist wherever the account has those fields.

A name the index does not carry contributes no matches rather than an error. The failure mode is therefore an empty result set that looks like "no such contact", not a 400 - so if a search returns nothing unexpectedly, check these names before concluding the data is absent. Sending only unrecognised names searches nothing and matches nothing.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

rlm_fields
Array of strings

Which columns to include in the exported spreadsheet, and in what order. Defaults to the standard column set for the record type.

This selects and orders; it cannot add. The export already has a column set - your organization's configured fields for the record type, plus the fixed columns that type's spreadsheet always carries. This parameter narrows that set to the names you list and reorders it to match the order you list them in. A name that is not already a column of yours contributes nothing; it does not create one.

The names are the response property names of the matching list endpoint - taskType, stage_name, created_at - plus the column names of your organization's custom fields. Read one page of the list endpoint to discover them.

Nothing validates this parameter, and no error tells you it was wrong. An unrecognised name is ignored rather than refused; if none of the names you send matches a column, the selection is empty rather than the request failing. Omitting the parameter and sending it empty are the same thing: both give the full default set.

Because the export is queued rather than rendered - the 200 says RLM accepted the job, not that a file exists - a mistake here surfaces in the delivered spreadsheet, not in this response. Verify against the file.

Responses

Response samples

Content type
application/json
{
  • "queued": true
}

Get a contact

Requires the Customer Management Module, exactly as GET /api/v3/companies/{id} does. Accounts without it get a 403.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a contact's leads

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
contact_id
required
integer
Example: 1234567

The RLM contact id.

query Parameters
page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a lead through its contact

Returns the lead with the given {id}.

The lead must belong to the contact named by {contact_id}; if it does not, or if that contact is not one of your organization's, the response is 404. A 200 here is therefore proof of the relationship.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
contact_id
required
integer
Example: 1234567

The RLM contact id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a contact's tasks

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
contact_id
required
integer
Example: 1234567

The RLM contact id.

query Parameters
page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a task through its contact

Returns the task with the given {id}.

The task must belong to the contact named by {contact_id}; if it does not, or if that contact is not one of your organization's, the response is 404. A 200 here is therefore proof of the relationship.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
contact_id
required
integer
Example: 1234567

The RLM contact id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a contact's journal entries

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
contact_id
required
integer
Example: 1234567

The RLM contact id.

query Parameters
description
string

Free-text search across journal entry text. Note that this parameter is called description but the field it searches is note - there is no description key on a journal entry.

sort_by
string

A relevance hint. It does not impose an order on the response, despite the name - treat it as advisory and do not build on it.

Journal entries always come back the same way: pinned entries first, then by the search engine's relevance score, descending. sort_by does not replace that. It is passed to the search engine as a boost on the named field, which can only move an entry by changing its score - and how much that moves anything, or whether it moves anything at all, depends on the scores already in play. A field name here is not a guarantee of ordering.

The value is one field name, not a list. A leading - weights the boost twice as heavily; it does not mean descending.

If you need a specific order, sort data client-side. No parameter on this endpoint will do it for you: journals and attachments are the two v3 collections that do not accept rlm_sorting.

The web app's journal screens do sort by column, which is why this parameter reads as though it should. They reach the same finder by a different route that applies a real database ordering. The API does not use that route.

journal_category_id
Array of integers

Restrict to one or more journal categories, by id.

No endpoint publishes the id list, so read the ids off the entries themselves: an entry that has a category carries journal_category_id beside a human-readable journal_category. Page through this collection unfiltered once and collect the pairs you find. An uncategorised entry carries neither, so skip those rather than treating them as a category.

That gives you the categories in use, not the full set - a category no entry has ever been given cannot be discovered this way, and there is no request that will list it. Cache what you harvest; the categories are shared reference data rather than per-account configuration, so the mapping does not vary between organizations and does not change often.

An id that matches nothing filters everything out and is not an error.

created_by_id
Array of integers

Restrict to entries created by one or more users, by user id.

v3 has no user directory endpoint. Discover ids the same way as for journal_category_id: an entry with a known author carries created_by_id beside that person's display name in created_by, and the same pairing holds for assigned_to_id and assigned_to. Harvesting those pairs is the only route from a person's name to their id.

The limits are worth stating plainly. You only learn about users who appear in entries you can already see, so this will not enumerate an organization's users, and a user who has written nothing is undiscoverable. Names are display names and are not unique - two people with the same name are two ids, and nothing here disambiguates them.

An id belonging to another organization returns no entries rather than an error, so an empty result does not confirm an id is valid.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a contact's journal entry

Returns the journal entry with the given {id}, restricted to entries on the contact identified by {contact_id}. An entry belonging to a different record returns 404.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
contact_id
required
integer
Example: 1234567

The RLM contact id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a contact's attachments

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
contact_id
required
integer
Example: 1234567

The RLM contact id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "edocs": [
    ]
}

Get a contact's attachment

Returns the attachment with the given {id}, restricted to attachments on the contact identified by {contact_id}. An attachment belonging to a different record returns 404.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
contact_id
required
integer
Example: 1234567

The RLM contact id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Samples

Physical product samples loaned to a customer during a sale, tracked by status. Also reachable under /api/v3/pipeline_samples.

List a lead's samples

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
lead_id
required
integer
Example: 1234567

The RLM lead id.

query Parameters
page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a sample through its lead

Returns the sample with the given {id}, restricted to samples on the lead identified by {lead_id}. Unlike the nested task and lead lookups, this one does honour the parent segment: a sample belonging to a different lead returns 404.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
lead_id
required
integer
Example: 1234567

The RLM lead id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List samples

Returns samples currently with a customer by default. Samples track physical product samples loaned out during a sale.

/api/v3/pipeline_samples is a complete alias for the sample paths - the list, the single record and the export all work under either spelling. /api/v3/samples is the shorter form and the one used throughout these docs.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

limit
integer
Example: limit=100

Alias for page[size]. Defaults to 100. Supplying this alone caps the result set but does not produce pagination links.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

List samples by status

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
filter
required
string
Enum: "with-customer" "on-order" "returned" "all"
Example: with-customer
  • with-customer - currently loaned out
  • on-order - ordered but not yet received
  • returned - returned by the customer
  • all - no status restriction

An unrecognised value falls back to all.

query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

page[number]
integer >= 1
Example: page[number]=1

Which page to return, starting at 1. Must be sent together with page[size] for pagination links to be generated.

page[size]
integer
Example: page[size]=100

Records per page. Defaults to 100 when omitted.

limit
integer
Example: limit=100

Alias for page[size]. Defaults to 100. Supplying this alone caps the result set but does not produce pagination links.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Queue a sample export

Queues a spreadsheet export of samples. See /api/v3/leads/list/{filter}/export for how exports are delivered.

/api/v3/pipeline_samples/export is an equivalent alias.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

rlm_fields
Array of strings

Which columns to include in the exported spreadsheet, and in what order. Defaults to the standard column set for the record type.

This selects and orders; it cannot add. The export already has a column set - your organization's configured fields for the record type, plus the fixed columns that type's spreadsheet always carries. This parameter narrows that set to the names you list and reorders it to match the order you list them in. A name that is not already a column of yours contributes nothing; it does not create one.

The names are the response property names of the matching list endpoint - taskType, stage_name, created_at - plus the column names of your organization's custom fields. Read one page of the list endpoint to discover them.

Nothing validates this parameter, and no error tells you it was wrong. An unrecognised name is ignored rather than refused; if none of the names you send matches a column, the selection is empty rather than the request failing. Omitting the parameter and sending it empty are the same thing: both give the full default set.

Because the export is queued rather than rendered - the 200 says RLM accepted the job, not that a file exists - a mistake here surfaces in the delivered spreadsheet, not in this response. Verify against the file.

Responses

Response samples

Content type
application/json
{
  • "queued": true
}

Queue a sample export for one status

Queues a spreadsheet export of the samples matching {filter}. Same behaviour as /api/v3/samples/export, restricted to one status.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
filter
required
string
Enum: "with-customer" "on-order" "returned" "all"
Example: with-customer
  • with-customer - currently loaned out
  • on-order - ordered but not yet received
  • returned - returned by the customer
  • all - no status restriction

An unrecognised value falls back to all.

query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

rlm_fields
Array of strings

Which columns to include in the exported spreadsheet, and in what order. Defaults to the standard column set for the record type.

This selects and orders; it cannot add. The export already has a column set - your organization's configured fields for the record type, plus the fixed columns that type's spreadsheet always carries. This parameter narrows that set to the names you list and reorders it to match the order you list them in. A name that is not already a column of yours contributes nothing; it does not create one.

The names are the response property names of the matching list endpoint - taskType, stage_name, created_at - plus the column names of your organization's custom fields. Read one page of the list endpoint to discover them.

Nothing validates this parameter, and no error tells you it was wrong. An unrecognised name is ignored rather than refused; if none of the names you send matches a column, the selection is empty rather than the request failing. Omitting the parameter and sending it empty are the same thing: both give the full default set.

Because the export is queued rather than rendered - the 200 says RLM accepted the job, not that a file exists - a mistake here surfaces in the delivered spreadsheet, not in this response. Verify against the file.

Responses

Response samples

Content type
application/json
{
  • "queued": true
}

Get a sample

/api/v3/pipeline_samples/{id} is an equivalent alias.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Journals

Journal entries are the activity history of a record. They are always accessed through their parent record.

List a lead's journal entries

Returns the lead's activity history. Entries are enriched with the display names of the related category, task type and users, alongside their ids. That enrichment happens only here - fetching a single entry by id returns the ids without the names.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
lead_id
required
integer
Example: 1234567

The RLM lead id.

query Parameters
description
string

Free-text search across journal entry text. Note that this parameter is called description but the field it searches is note - there is no description key on a journal entry.

sort_by
string

A relevance hint. It does not impose an order on the response, despite the name - treat it as advisory and do not build on it.

Journal entries always come back the same way: pinned entries first, then by the search engine's relevance score, descending. sort_by does not replace that. It is passed to the search engine as a boost on the named field, which can only move an entry by changing its score - and how much that moves anything, or whether it moves anything at all, depends on the scores already in play. A field name here is not a guarantee of ordering.

The value is one field name, not a list. A leading - weights the boost twice as heavily; it does not mean descending.

If you need a specific order, sort data client-side. No parameter on this endpoint will do it for you: journals and attachments are the two v3 collections that do not accept rlm_sorting.

The web app's journal screens do sort by column, which is why this parameter reads as though it should. They reach the same finder by a different route that applies a real database ordering. The API does not use that route.

journal_category_id
Array of integers

Restrict to one or more journal categories, by id.

No endpoint publishes the id list, so read the ids off the entries themselves: an entry that has a category carries journal_category_id beside a human-readable journal_category. Page through this collection unfiltered once and collect the pairs you find. An uncategorised entry carries neither, so skip those rather than treating them as a category.

That gives you the categories in use, not the full set - a category no entry has ever been given cannot be discovered this way, and there is no request that will list it. Cache what you harvest; the categories are shared reference data rather than per-account configuration, so the mapping does not vary between organizations and does not change often.

An id that matches nothing filters everything out and is not an error.

created_by_id
Array of integers

Restrict to entries created by one or more users, by user id.

v3 has no user directory endpoint. Discover ids the same way as for journal_category_id: an entry with a known author carries created_by_id beside that person's display name in created_by, and the same pairing holds for assigned_to_id and assigned_to. Harvesting those pairs is the only route from a person's name to their id.

The limits are worth stating plainly. You only learn about users who appear in entries you can already see, so this will not enumerate an organization's users, and a user who has written nothing is undiscoverable. Names are display names and are not unique - two people with the same name are two ids, and nothing here disambiguates them.

An id belonging to another organization returns no entries rather than an error, so an empty result does not confirm an id is valid.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a journal entry

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
lead_id
required
integer
Example: 1234567

The RLM lead id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a task's journal entries

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
task_id
required
integer
Example: 1234567

The RLM task id.

query Parameters
description
string

Free-text search across journal entry text. Note that this parameter is called description but the field it searches is note - there is no description key on a journal entry.

sort_by
string

A relevance hint. It does not impose an order on the response, despite the name - treat it as advisory and do not build on it.

Journal entries always come back the same way: pinned entries first, then by the search engine's relevance score, descending. sort_by does not replace that. It is passed to the search engine as a boost on the named field, which can only move an entry by changing its score - and how much that moves anything, or whether it moves anything at all, depends on the scores already in play. A field name here is not a guarantee of ordering.

The value is one field name, not a list. A leading - weights the boost twice as heavily; it does not mean descending.

If you need a specific order, sort data client-side. No parameter on this endpoint will do it for you: journals and attachments are the two v3 collections that do not accept rlm_sorting.

The web app's journal screens do sort by column, which is why this parameter reads as though it should. They reach the same finder by a different route that applies a real database ordering. The API does not use that route.

journal_category_id
Array of integers

Restrict to one or more journal categories, by id.

No endpoint publishes the id list, so read the ids off the entries themselves: an entry that has a category carries journal_category_id beside a human-readable journal_category. Page through this collection unfiltered once and collect the pairs you find. An uncategorised entry carries neither, so skip those rather than treating them as a category.

That gives you the categories in use, not the full set - a category no entry has ever been given cannot be discovered this way, and there is no request that will list it. Cache what you harvest; the categories are shared reference data rather than per-account configuration, so the mapping does not vary between organizations and does not change often.

An id that matches nothing filters everything out and is not an error.

created_by_id
Array of integers

Restrict to entries created by one or more users, by user id.

v3 has no user directory endpoint. Discover ids the same way as for journal_category_id: an entry with a known author carries created_by_id beside that person's display name in created_by, and the same pairing holds for assigned_to_id and assigned_to. Harvesting those pairs is the only route from a person's name to their id.

The limits are worth stating plainly. You only learn about users who appear in entries you can already see, so this will not enumerate an organization's users, and a user who has written nothing is undiscoverable. Names are display names and are not unique - two people with the same name are two ids, and nothing here disambiguates them.

An id belonging to another organization returns no entries rather than an error, so an empty result does not confirm an id is valid.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a task's journal entry

Returns the journal entry with the given {id}, restricted to entries on the task identified by {task_id}. An entry belonging to a different record returns 404.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
task_id
required
integer
Example: 1234567

The RLM task id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a company's journal entries

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
company_id
required
integer
Example: 1234567

The RLM company id.

query Parameters
description
string

Free-text search across journal entry text. Note that this parameter is called description but the field it searches is note - there is no description key on a journal entry.

sort_by
string

A relevance hint. It does not impose an order on the response, despite the name - treat it as advisory and do not build on it.

Journal entries always come back the same way: pinned entries first, then by the search engine's relevance score, descending. sort_by does not replace that. It is passed to the search engine as a boost on the named field, which can only move an entry by changing its score - and how much that moves anything, or whether it moves anything at all, depends on the scores already in play. A field name here is not a guarantee of ordering.

The value is one field name, not a list. A leading - weights the boost twice as heavily; it does not mean descending.

If you need a specific order, sort data client-side. No parameter on this endpoint will do it for you: journals and attachments are the two v3 collections that do not accept rlm_sorting.

The web app's journal screens do sort by column, which is why this parameter reads as though it should. They reach the same finder by a different route that applies a real database ordering. The API does not use that route.

journal_category_id
Array of integers

Restrict to one or more journal categories, by id.

No endpoint publishes the id list, so read the ids off the entries themselves: an entry that has a category carries journal_category_id beside a human-readable journal_category. Page through this collection unfiltered once and collect the pairs you find. An uncategorised entry carries neither, so skip those rather than treating them as a category.

That gives you the categories in use, not the full set - a category no entry has ever been given cannot be discovered this way, and there is no request that will list it. Cache what you harvest; the categories are shared reference data rather than per-account configuration, so the mapping does not vary between organizations and does not change often.

An id that matches nothing filters everything out and is not an error.

created_by_id
Array of integers

Restrict to entries created by one or more users, by user id.

v3 has no user directory endpoint. Discover ids the same way as for journal_category_id: an entry with a known author carries created_by_id beside that person's display name in created_by, and the same pairing holds for assigned_to_id and assigned_to. Harvesting those pairs is the only route from a person's name to their id.

The limits are worth stating plainly. You only learn about users who appear in entries you can already see, so this will not enumerate an organization's users, and a user who has written nothing is undiscoverable. Names are display names and are not unique - two people with the same name are two ids, and nothing here disambiguates them.

An id belonging to another organization returns no entries rather than an error, so an empty result does not confirm an id is valid.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a company's journal entry

Returns the journal entry with the given {id}, restricted to entries on the company identified by {company_id}. An entry belonging to a different record returns 404.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
company_id
required
integer
Example: 1234567

The RLM company id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a contact's journal entries

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
contact_id
required
integer
Example: 1234567

The RLM contact id.

query Parameters
description
string

Free-text search across journal entry text. Note that this parameter is called description but the field it searches is note - there is no description key on a journal entry.

sort_by
string

A relevance hint. It does not impose an order on the response, despite the name - treat it as advisory and do not build on it.

Journal entries always come back the same way: pinned entries first, then by the search engine's relevance score, descending. sort_by does not replace that. It is passed to the search engine as a boost on the named field, which can only move an entry by changing its score - and how much that moves anything, or whether it moves anything at all, depends on the scores already in play. A field name here is not a guarantee of ordering.

The value is one field name, not a list. A leading - weights the boost twice as heavily; it does not mean descending.

If you need a specific order, sort data client-side. No parameter on this endpoint will do it for you: journals and attachments are the two v3 collections that do not accept rlm_sorting.

The web app's journal screens do sort by column, which is why this parameter reads as though it should. They reach the same finder by a different route that applies a real database ordering. The API does not use that route.

journal_category_id
Array of integers

Restrict to one or more journal categories, by id.

No endpoint publishes the id list, so read the ids off the entries themselves: an entry that has a category carries journal_category_id beside a human-readable journal_category. Page through this collection unfiltered once and collect the pairs you find. An uncategorised entry carries neither, so skip those rather than treating them as a category.

That gives you the categories in use, not the full set - a category no entry has ever been given cannot be discovered this way, and there is no request that will list it. Cache what you harvest; the categories are shared reference data rather than per-account configuration, so the mapping does not vary between organizations and does not change often.

An id that matches nothing filters everything out and is not an error.

created_by_id
Array of integers

Restrict to entries created by one or more users, by user id.

v3 has no user directory endpoint. Discover ids the same way as for journal_category_id: an entry with a known author carries created_by_id beside that person's display name in created_by, and the same pairing holds for assigned_to_id and assigned_to. Harvesting those pairs is the only route from a person's name to their id.

The limits are worth stating plainly. You only learn about users who appear in entries you can already see, so this will not enumerate an organization's users, and a user who has written nothing is undiscoverable. Names are display names and are not unique - two people with the same name are two ids, and nothing here disambiguates them.

An id belonging to another organization returns no entries rather than an error, so an empty result does not confirm an id is valid.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Get a contact's journal entry

Returns the journal entry with the given {id}, restricted to entries on the contact identified by {contact_id}. An entry belonging to a different record returns 404.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
contact_id
required
integer
Example: 1234567

The RLM contact id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Attachments

Attachment metadata for a record. Always accessed through the parent record. The response describes the files and links to them; it does not embed their contents.

List a lead's attachments

Returns attachment metadata and download links. This endpoint is not paginated - it returns every attachment on the record.

For organizations with a BMS integration active, an additional edocs key lists electronic documents held in the connected system. Those entries look like attachments but their links are session-authenticated RLM URLs, not direct file links - read the Edoc schema before planning to fetch them.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
lead_id
required
integer
Example: 1234567

The RLM lead id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "edocs": [
    ]
}

Get an attachment

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
lead_id
required
integer
Example: 1234567

The RLM lead id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a task's attachments

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
task_id
required
integer
Example: 1234567

The RLM task id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "edocs": [
    ]
}

Get a task's attachment

Returns the attachment with the given {id}, restricted to attachments on the task identified by {task_id}. An attachment belonging to a different record returns 404.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
task_id
required
integer
Example: 1234567

The RLM task id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a company's attachments

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
company_id
required
integer
Example: 1234567

The RLM company id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "edocs": [
    ]
}

Get a company's attachment

Returns the attachment with the given {id}, restricted to attachments on the company identified by {company_id}. An attachment belonging to a different record returns 404.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
company_id
required
integer
Example: 1234567

The RLM company id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a contact's attachments

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
contact_id
required
integer
Example: 1234567

The RLM contact id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "edocs": [
    ]
}

Get a contact's attachment

Returns the attachment with the given {id}, restricted to attachments on the contact identified by {contact_id}. An attachment belonging to a different record returns 404.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
contact_id
required
integer
Example: 1234567

The RLM contact id.

id
required
integer
Example: 1234567

The RLM record id.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Exports

Exports are generated asynchronously and delivered to the requesting user out of band. The endpoint returns immediately with a queue acknowledgement, not a file.

Queue an export of all leads

Queues a spreadsheet export of all open leads and returns immediately. The file is delivered to the authenticating user out of band once generated - it is not returned in the response body.

This is the same operation as /api/v3/leads/list/{filter}/export with {filter} set to open, which is the default when the segment is absent.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

rlm_fields
Array of strings

Which columns to include in the exported spreadsheet, and in what order. Defaults to the standard column set for the record type.

This selects and orders; it cannot add. The export already has a column set - your organization's configured fields for the record type, plus the fixed columns that type's spreadsheet always carries. This parameter narrows that set to the names you list and reorders it to match the order you list them in. A name that is not already a column of yours contributes nothing; it does not create one.

The names are the response property names of the matching list endpoint - taskType, stage_name, created_at - plus the column names of your organization's custom fields. Read one page of the list endpoint to discover them.

Nothing validates this parameter, and no error tells you it was wrong. An unrecognised name is ignored rather than refused; if none of the names you send matches a column, the selection is empty rather than the request failing. Omitting the parameter and sending it empty are the same thing: both give the full default set.

Because the export is queued rather than rendered - the 200 says RLM accepted the job, not that a file exists - a mistake here surfaces in the delivered spreadsheet, not in this response. Verify against the file.

Responses

Response samples

Content type
application/json
{
  • "queued": true
}

Queue a lead export

Queues a spreadsheet export of the leads matching this request and returns immediately. The file is delivered to the authenticating user out of band once generated - it is not returned in the response body.

Accepts the same filtering, search and sorting parameters as the corresponding list endpoint, so you can export exactly the set you would otherwise page through. Use all as the {filter} to export everything.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
filter
required
string
Enum: "open" "closed" "all" "deleted"
Example: all
query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

rlm_fields
Array of strings

Which columns to include in the exported spreadsheet, and in what order. Defaults to the standard column set for the record type.

This selects and orders; it cannot add. The export already has a column set - your organization's configured fields for the record type, plus the fixed columns that type's spreadsheet always carries. This parameter narrows that set to the names you list and reorders it to match the order you list them in. A name that is not already a column of yours contributes nothing; it does not create one.

The names are the response property names of the matching list endpoint - taskType, stage_name, created_at - plus the column names of your organization's custom fields. Read one page of the list endpoint to discover them.

Nothing validates this parameter, and no error tells you it was wrong. An unrecognised name is ignored rather than refused; if none of the names you send matches a column, the selection is empty rather than the request failing. Omitting the parameter and sending it empty are the same thing: both give the full default set.

Because the export is queued rather than rendered - the 200 says RLM accepted the job, not that a file exists - a mistake here surfaces in the delivered spreadsheet, not in this response. Verify against the file.

Responses

Response samples

Content type
application/json
{
  • "queued": true
}

Queue an export of all tasks

Queues a spreadsheet export of all tasks and returns immediately. The file is delivered to the authenticating user out of band once generated - it is not returned in the response body.

This is the same operation as /api/v3/tasks/list/{filter}/export with {filter} set to all, which is the default when the segment is absent.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

rlm_fields
Array of strings

Which columns to include in the exported spreadsheet, and in what order. Defaults to the standard column set for the record type.

This selects and orders; it cannot add. The export already has a column set - your organization's configured fields for the record type, plus the fixed columns that type's spreadsheet always carries. This parameter narrows that set to the names you list and reorders it to match the order you list them in. A name that is not already a column of yours contributes nothing; it does not create one.

The names are the response property names of the matching list endpoint - taskType, stage_name, created_at - plus the column names of your organization's custom fields. Read one page of the list endpoint to discover them.

Nothing validates this parameter, and no error tells you it was wrong. An unrecognised name is ignored rather than refused; if none of the names you send matches a column, the selection is empty rather than the request failing. Omitting the parameter and sending it empty are the same thing: both give the full default set.

Because the export is queued rather than rendered - the 200 says RLM accepted the job, not that a file exists - a mistake here surfaces in the delivered spreadsheet, not in this response. Verify against the file.

Responses

Response samples

Content type
application/json
{
  • "queued": true
}

Queue a task export

Queues a spreadsheet export of the matching tasks. See /api/v3/leads/list/{filter}/export for how exports are delivered.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
filter
required
string
Enum: "incomplete" "completed" "deleted" "all"
Example: all
query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

rlm_fields
Array of strings

Which columns to include in the exported spreadsheet, and in what order. Defaults to the standard column set for the record type.

This selects and orders; it cannot add. The export already has a column set - your organization's configured fields for the record type, plus the fixed columns that type's spreadsheet always carries. This parameter narrows that set to the names you list and reorders it to match the order you list them in. A name that is not already a column of yours contributes nothing; it does not create one.

The names are the response property names of the matching list endpoint - taskType, stage_name, created_at - plus the column names of your organization's custom fields. Read one page of the list endpoint to discover them.

Nothing validates this parameter, and no error tells you it was wrong. An unrecognised name is ignored rather than refused; if none of the names you send matches a column, the selection is empty rather than the request failing. Omitting the parameter and sending it empty are the same thing: both give the full default set.

Because the export is queued rather than rendered - the 200 says RLM accepted the job, not that a file exists - a mistake here surfaces in the delivered spreadsheet, not in this response. Verify against the file.

Responses

Response samples

Content type
application/json
{
  • "queued": true
}

Queue an export of all companies

Queues a spreadsheet export of all companies and returns immediately. The file is delivered to the authenticating user out of band once generated - it is not returned in the response body.

This is the same operation as /api/v3/companies/list/{filter}/export with {filter} set to all, which is the default when the segment is absent.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

rlm_fields
Array of strings

Which columns to include in the exported spreadsheet, and in what order. Defaults to the standard column set for the record type.

This selects and orders; it cannot add. The export already has a column set - your organization's configured fields for the record type, plus the fixed columns that type's spreadsheet always carries. This parameter narrows that set to the names you list and reorders it to match the order you list them in. A name that is not already a column of yours contributes nothing; it does not create one.

The names are the response property names of the matching list endpoint - taskType, stage_name, created_at - plus the column names of your organization's custom fields. Read one page of the list endpoint to discover them.

Nothing validates this parameter, and no error tells you it was wrong. An unrecognised name is ignored rather than refused; if none of the names you send matches a column, the selection is empty rather than the request failing. Omitting the parameter and sending it empty are the same thing: both give the full default set.

Because the export is queued rather than rendered - the 200 says RLM accepted the job, not that a file exists - a mistake here surfaces in the delivered spreadsheet, not in this response. Verify against the file.

Responses

Response samples

Content type
application/json
{
  • "queued": true
}

Queue a company export

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
filter
required
string
Enum: "all" "deleted"
Example: all
  • all - active records
  • deleted - soft-deleted records

An unrecognised value falls back to all.

query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

rlm_fields
Array of strings

Which columns to include in the exported spreadsheet, and in what order. Defaults to the standard column set for the record type.

This selects and orders; it cannot add. The export already has a column set - your organization's configured fields for the record type, plus the fixed columns that type's spreadsheet always carries. This parameter narrows that set to the names you list and reorders it to match the order you list them in. A name that is not already a column of yours contributes nothing; it does not create one.

The names are the response property names of the matching list endpoint - taskType, stage_name, created_at - plus the column names of your organization's custom fields. Read one page of the list endpoint to discover them.

Nothing validates this parameter, and no error tells you it was wrong. An unrecognised name is ignored rather than refused; if none of the names you send matches a column, the selection is empty rather than the request failing. Omitting the parameter and sending it empty are the same thing: both give the full default set.

Because the export is queued rather than rendered - the 200 says RLM accepted the job, not that a file exists - a mistake here surfaces in the delivered spreadsheet, not in this response. Verify against the file.

Responses

Response samples

Content type
application/json
{
  • "queued": true
}

Queue an export of all contacts

Queues a spreadsheet export of all contacts and returns immediately. The file is delivered to the authenticating user out of band once generated - it is not returned in the response body.

This is the same operation as /api/v3/contacts/list/{filter}/export with {filter} set to all, which is the default when the segment is absent.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

match_fields
Array of strings

Which fields query searches. Defaults to name. Accepts an array; it has no effect unless query is also supplied.

The accepted names are contact search index fields, the same set rlm_sorting draws on, so the same discovery path applies: every property of the contacts this endpoint returns is a valid name. Two are present on every account - name and company_names - and the rest depend on which fields the account has configured. A configured field is addressed through its display sub-key, as <column_name>.display; RLM's own contact search sends first_name.display, last_name.display and email.display alongside name, and those exist wherever the account has those fields.

A name the index does not carry contributes no matches rather than an error. The failure mode is therefore an empty result set that looks like "no such contact", not a 400 - so if a search returns nothing unexpectedly, check these names before concluding the data is absent. Sending only unrecognised names searches nothing and matches nothing.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

rlm_fields
Array of strings

Which columns to include in the exported spreadsheet, and in what order. Defaults to the standard column set for the record type.

This selects and orders; it cannot add. The export already has a column set - your organization's configured fields for the record type, plus the fixed columns that type's spreadsheet always carries. This parameter narrows that set to the names you list and reorders it to match the order you list them in. A name that is not already a column of yours contributes nothing; it does not create one.

The names are the response property names of the matching list endpoint - taskType, stage_name, created_at - plus the column names of your organization's custom fields. Read one page of the list endpoint to discover them.

Nothing validates this parameter, and no error tells you it was wrong. An unrecognised name is ignored rather than refused; if none of the names you send matches a column, the selection is empty rather than the request failing. Omitting the parameter and sending it empty are the same thing: both give the full default set.

Because the export is queued rather than rendered - the 200 says RLM accepted the job, not that a file exists - a mistake here surfaces in the delivered spreadsheet, not in this response. Verify against the file.

Responses

Response samples

Content type
application/json
{
  • "queued": true
}

Queue a contact export

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
filter
required
string
Enum: "all" "deleted"
Example: all
  • all - active records
  • deleted - soft-deleted records

An unrecognised value falls back to all.

query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

match_fields
Array of strings

Which fields query searches. Defaults to name. Accepts an array; it has no effect unless query is also supplied.

The accepted names are contact search index fields, the same set rlm_sorting draws on, so the same discovery path applies: every property of the contacts this endpoint returns is a valid name. Two are present on every account - name and company_names - and the rest depend on which fields the account has configured. A configured field is addressed through its display sub-key, as <column_name>.display; RLM's own contact search sends first_name.display, last_name.display and email.display alongside name, and those exist wherever the account has those fields.

A name the index does not carry contributes no matches rather than an error. The failure mode is therefore an empty result set that looks like "no such contact", not a 400 - so if a search returns nothing unexpectedly, check these names before concluding the data is absent. Sending only unrecognised names searches nothing and matches nothing.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

rlm_fields
Array of strings

Which columns to include in the exported spreadsheet, and in what order. Defaults to the standard column set for the record type.

This selects and orders; it cannot add. The export already has a column set - your organization's configured fields for the record type, plus the fixed columns that type's spreadsheet always carries. This parameter narrows that set to the names you list and reorders it to match the order you list them in. A name that is not already a column of yours contributes nothing; it does not create one.

The names are the response property names of the matching list endpoint - taskType, stage_name, created_at - plus the column names of your organization's custom fields. Read one page of the list endpoint to discover them.

Nothing validates this parameter, and no error tells you it was wrong. An unrecognised name is ignored rather than refused; if none of the names you send matches a column, the selection is empty rather than the request failing. Omitting the parameter and sending it empty are the same thing: both give the full default set.

Because the export is queued rather than rendered - the 200 says RLM accepted the job, not that a file exists - a mistake here surfaces in the delivered spreadsheet, not in this response. Verify against the file.

Responses

Response samples

Content type
application/json
{
  • "queued": true
}

Queue a sample export

Queues a spreadsheet export of samples. See /api/v3/leads/list/{filter}/export for how exports are delivered.

/api/v3/pipeline_samples/export is an equivalent alias.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

rlm_fields
Array of strings

Which columns to include in the exported spreadsheet, and in what order. Defaults to the standard column set for the record type.

This selects and orders; it cannot add. The export already has a column set - your organization's configured fields for the record type, plus the fixed columns that type's spreadsheet always carries. This parameter narrows that set to the names you list and reorders it to match the order you list them in. A name that is not already a column of yours contributes nothing; it does not create one.

The names are the response property names of the matching list endpoint - taskType, stage_name, created_at - plus the column names of your organization's custom fields. Read one page of the list endpoint to discover them.

Nothing validates this parameter, and no error tells you it was wrong. An unrecognised name is ignored rather than refused; if none of the names you send matches a column, the selection is empty rather than the request failing. Omitting the parameter and sending it empty are the same thing: both give the full default set.

Because the export is queued rather than rendered - the 200 says RLM accepted the job, not that a file exists - a mistake here surfaces in the delivered spreadsheet, not in this response. Verify against the file.

Responses

Response samples

Content type
application/json
{
  • "queued": true
}

Queue a sample export for one status

Queues a spreadsheet export of the samples matching {filter}. Same behaviour as /api/v3/samples/export, restricted to one status.

Authorizations:
(OrganizationApiKeyUserEmailUserApiKey)
path Parameters
filter
required
string
Enum: "with-customer" "on-order" "returned" "all"
Example: with-customer
  • with-customer - currently loaned out
  • on-order - ordered but not yet received
  • returned - returned by the customer
  • all - no status restriction

An unrecognised value falls back to all.

query Parameters
query
string
Example: query=smith

Full-text search across the record. Omit it, or pass *, to match everything.

object

Per-field filters, keyed by field name - for example rlm_filters[stage_name]=Sold.

Values may be a scalar, an array (matches any), or an object using the gt / gte / lt / lte / eq range operators on date and number fields, or empty on any field. See the Filtering section of the introduction for the full syntax. Unrecognised field names are ignored.

object

Multi-field sorting, keyed by field name, each with a direction (asc or desc) and a priority (lower sorts first) - for example rlm_sorting[updated_at][direction]=desc&rlm_sorting[updated_at][priority]=0.

Which names are accepted is computed per request, so this document does not print a list. The server builds the permitted set from the search index for the record type being listed: every indexed field, plus every multi-field beneath one. That index carries each organization's own custom fields, so the set differs between accounts and grows when an account adds a field. Any list printed here would be wrong for most callers and would go stale for the rest.

What you can rely on: every property of the objects this endpoint returns is a sortable name. That is the discovery path - read one page and take the keys.

Sortable and filterable are not the same set, and sortable is the smaller one. What you may sort on is the index; what you may filter on is the index plus the fields your account has configured. rlm_filters adds those deliberately, so that a field which exists in your configuration but has never been given a value can still be filtered on. rlm_sorting does not. A brand-new custom field with no data in it is therefore filterable and not sortable, and asking to sort by it is silently ignored rather than refused.

So do not derive one list from the other, and do not conclude a name is invalid because sorting by it did nothing.

Multi-fields are those same names with a suffix. .ci is the case-insensitive form and .keyword the exact one; contacts and companies also carry .word_start. Sorting text is normally done on .ci, which is what RLM's own grids send: rlm_sorting[taskType.ci][direction]=asc. Sorting on the bare text form of a field gives an order that is rarely the one you want; use .ci, or .keyword when you need the exact form.

An unrecognised name is dropped, not rejected. The object is filtered down to permitted keys before anything reads it, so a misspelt field name returns 200 in the endpoint's default order rather than an error, and a request whose keys are all misspelt sorts as though you had sent none. Check the order you got back rather than assuming the key was honoured.

rlm_fields
Array of strings

Which columns to include in the exported spreadsheet, and in what order. Defaults to the standard column set for the record type.

This selects and orders; it cannot add. The export already has a column set - your organization's configured fields for the record type, plus the fixed columns that type's spreadsheet always carries. This parameter narrows that set to the names you list and reorders it to match the order you list them in. A name that is not already a column of yours contributes nothing; it does not create one.

The names are the response property names of the matching list endpoint - taskType, stage_name, created_at - plus the column names of your organization's custom fields. Read one page of the list endpoint to discover them.

Nothing validates this parameter, and no error tells you it was wrong. An unrecognised name is ignored rather than refused; if none of the names you send matches a column, the selection is empty rather than the request failing. Omitting the parameter and sending it empty are the same thing: both give the full default set.

Because the export is queued rather than rendered - the 200 says RLM accepted the job, not that a file exists - a mistake here surfaces in the delivered spreadsheet, not in this response. Verify against the file.

Responses

Response samples

Content type
application/json
{
  • "queued": true
}