Making requests
Content Negotiation
The Outreach API implements the JSON API 1.0 specification. All requests must specify the JSON API media type (application/vnd.api+json
) within the Content-Type
request header.
Requests failing to specify this content type will receive a 415 HTTP response with a descriptive error message:{
errors: [
{
id: "unsupportedMediaType",
title: "Unsupported Media Type",
details: "Expected Content-Type header to be 'application/vnd.api+json'.",
},
],
}
Fetch a Collection of Resources
To fetch a collection of resources, make aGET
request against a resource's pluralized type. The body of the response
will be a JSON payload. If the request was successful, the response will contain a top-level data
property; otherwise,
the response will contain a top-level errors
property containing a list of error reasons.
See Error Responses for more details.Request
GET https://api.outreach.io/api/v2/prospects
Response
{
data: [
{
type: "prospect",
id: 1,
attributes: {
firstName: "Sally",
lastName: null,
//...
},
relationships: {
account: {
data: {
type: "account",
id: 1,
},
},
mailings: {
links: {
related: "https://api.outreach.io/api/v2/mailings?filter[prospect][id]=1",
},
},
//...
},
},
//...
],
}
type
and id
values of the resource, but may also
contain properties for the resource's attributes
and relationships
, as well as meta
data.This resource object contains two types of relationship information. The account
relationship contains a data
property with type
and id
values. When we reference just a resource's type and ID, we call the object a resource
identifier. The mailings
relationship, however, does not contain a data property. Instead, it provides a links
property with a related
URL that references the list of mailings associated with this prospect. Relationship objects
may contain data
, links
or meta
properties.For more information, see Fetching Resources in the JSON API
specification.Filter and Sort
Oftentimes we want to return just a specific subset of a resource collection. The Outreach API provides two query parameters for specifying collections:
filter
sort
Filter parameters restrict collections by certain key-value combinations; the sort parameter orders collections by attributes and relationships' attributes; See the following examples for more details.
Note that not all attributes permit filter and sort criteria. Please consult the API Reference for more details.
Filter by exact attribute
GET https://api.outreach.io/api/v2/prospects?filter[firstName]=Sally
Filter by exact relationship's attribute
Update (May, 2023): In order to maintain the performance and reliability of our API services and allow modernization of our service architecture, Outreach has decided to deprecate support for filtering by some of the relationship's attributes.
filter[relationship_abc][attribute_1]=Acme
,
or only filter[relationship_abc][id]=1
is allowed. In the latter case you need to do two requests, first get a list of relationship IDs querying
/api/v2/model_abc?filter[name]=Acme
and then pass them to the original query as filter[relationship_abc][id]=1,2,3
.GET https://api.outreach.io/api/v2/prospects?filter[account][name]=Acme // deprecated
GET https://api.outreach.io/api/v2/account?filter[name]=Acme
GET https://api.outreach.io/api/v2/prospects?filter[account][id]=1,2,3,5,8,13
Filter by exact attribute and relationship's attribute
GET https://api.outreach.io/api/v2/prospects?filter[firstName]=Sally&filter[account][name]=Acme
Filter by a list of values
GET https://api.outreach.io/api/v2/prospects?filter[id]=1,2,3,5,8,13
Filter by range of values
GET https://api.outreach.io/api/v2/prospects?filter[id]=5..10
Filter by a less-than-or-equal-to condition
GET https://api.outreach.io/api/v2/prospects?filter[updatedAt]=neginf..2017-01-01
Filter by greater-than-or-equal-to condition
GET https://api.outreach.io/api/v2/prospects?filter[updatedAt]=2017-01-01..inf
Filter NULL values
There are two special values supported by all filterable attributes that can be used to select NULLs or NOT NULLs:
GET https://api.outreach.io/api/v2/accounts?filter[buyerIntentScore]=__null__
GET https://api.outreach.io/api/v2/accounts?filter[buyerIntentScore]=__notnull__
Sort by ascending attribute
GET https://api.outreach.io/api/v2/prospects?sort=firstName
Sort by descending attribute
GET https://api.outreach.io/api/v2/prospects?sort=-firstName
Sort by relationship's attribute (deprecated)
Update (May, 2023): In order to maintain the performance and reliability of our API services and allow modernization of our service architecture, Outreach has decided to deprecate support for sorting by the relationship's attributes.
Please fetch the result of your query with the relationship's attribute included and apply sorting locally in your service.
GET https://api.outreach.io/api/v2/prospects?sort=account.name // deprecated
Sort by multiple criteria
GET https://api.outreach.io/api/v2/prospects?sort=lastName,-firstName
New filter syntax
We have added a new parameter,newFilterSyntax=true
, that you can use when you need to match values that contain the
comma character (,
) or two dots (..
). This was not possible with the old syntax as the comma character and the two
dots had special meaning.Instead of separating the values with commas, you now use brackets to list an array of values. This means you can use a literal comma in the value. Example:
# old syntax: GET https://api.outreach.io/api/v2/prospects?filter[firstName]=Sally,Katie # new syntax: GET https://api.outreach.io/api/v2/prospects?newFilterSyntax=true&filter[firstName][]=Sally&filter[firstName][]=Katie # old syntax (does not return the desired result, filters for accounts named "Company" and " Inc"): GET https://api.outreach.io/api/v2/accounts?filter[name]=Company,%20Inc # new syntax (filters for "Company, Inc"): GET https://api.outreach.io/api/v2/accounts?newFilterSyntax=true&filter[name][]=Company,%20Inc
[gte]
and [lte]
(gte
is short for
greater-than-or-equal-to, and lte
is short for less-than-or-equal-to). So instead of 5..10
you use [gte]=5
and [lte]=10
. This means you can use two dots when filtering for values. Instead of neginf
and inf
, simply leave
out either [gte]
or [lte]
instead. Example:# old syntax: GET https://api.outreach.io/api/v2/prospects?filter[id]=5..10 # new syntax: GET https://api.outreach.io/api/v2/prospects?newFilterSyntax=true&filter[id][gte]=5&filter[id][lte]=10 # old syntax: GET https://api.outreach.io/api/v2/prospects?filter[updatedAt]=neginf..2017-01-01 # new syntax: GET https://api.outreach.io/api/v2/prospects?newFilterSyntax=true&filter[updatedAt][lte]=2017-01-01
Pagination
If after using sort and filter you need to further reduce the number of returned entries, you can use pagination. The Outreach API providespage
query parameter for this purpose. Page size/limit and offset parameters limit views into
large collections. See the following examples for more details.Cursor-based Pagination
Cursor-based pagination works by returning a pointer to a specific item in the dataset.
GET https://api.outreach.io/api/v2/prospects?page[size]=50&count=false
links
property with first
, prev
and next
links that allow efficient pagination.
Using it with the count=false
query parameter is recommended to improve performance of the query.{
data: [
//...
],
links: {
first: "https://api.outreach.io/api/v2/prospects?page[size]=50",
prev: "https://api.outreach.io/api/v2/prospects?page[size]=50&page[before]=eyJjbiI6IkFwaVYyOjpQcm9zcGVjdHNDb250cm9sbGVyIiwic3AiOm51bGwsInN2IjpbXSwiaWQiOjEzNiwidiI6MX0",
next: "https://api.outreach.io/api/v2/prospects?page[size]=50&page[after]=eyJjbiI6IkFwaVYyOjpQcm9zcGVjdHNDb250cm9sbGVyIiwic3AiOm51bGwsInN2IjpbXSwiaWQiOjIyNSwidiI6MX0"
},
}
Offset Pagination (Deprecated)
Please use the cursor-based pagination described above and the top-levellinks
property to advance to next page.To offset the page start:
GET https://api.outreach.io/api/v2/prospects?page[offset]=50
Note that large offsets on large collections can cause a significant performance hit. For this reason we enforce a maximum offset of 10,000. To work around this limitation, consider using more specific filter criteria or paging across ranges of IDs.
To limit the page size:
GET https://api.outreach.io/api/v2/prospects?page[limit]=3
Note that page limits must not be larger than 1000.
In addition, each collection response will include a top-levellinks
property that will
contain first
, prev
, next
and last
keys, if applicable. Use these links to easily navigate between slices of a
collection.Request
GET https://api.outreach.io/api/v2/prospects?page[offset]=150
Response
{
data: [
//...
],
links: {
first: "https://api.outreach.io/api/v2/prospects?page[limit]=50&page[offset]=0",
prev: "https://api.outreach.io/api/v2/prospects?page[limit]=50&page[offset]=100",
next: "https://api.outreach.io/api/v2/prospects?page[limit]=50&page[offset]=200",
last: "https://api.outreach.io/api/v2/prospects?page[limit]=50&page[offset]=850",
},
}
Counting resources
It is possible to count the resources matching certain filter criteria using the collection query. Just add a query parametercount
:GET https://api.outreach.io/api/v2/prospects?filter[firstName]=Sally&count=true
data
property that is followed by meta
containing total number of matching prospects:{
data: [
//...
],
meta: {
count: 53,
count_truncated: false
},
links: {
//...
}
}
In case there are no matching resources the response is short:
{
data: [],
meta: {
count: 0,
count_truncated: false
},
links: {
//...
}
}
When is count truncated?
Counting all resources matching specific filter criteria is often a more expensive operation than finding a next page of data. In order to limit the effect of count queries on the overall system performance Outreach has implemented following control mechanisms.
Max total count - stops counter upon the discovery of 2,000,000 matching resources. A sample response is:
{
data: [
//...
],
meta: {
count: 2000000,
count_truncated: true
},
links: {
//...
}
}
Resource utilization throttling - in case the system is under extreme load there is a dedicated throttling applied for count queries to avoid amplification of the resource utilization. In such case the next page of data is returned but the count value is not known and the response is the following:
{
data: [
//...
],
meta: {
count: 0,
count_truncated: true
},
links: {
//...
}
}
Fetch an Individual Resource
You can fetch individual resources by making aGET
request against any particular resource's pluralized type and ID
combination. For example, to retrieve an individual prospect resource:GET https://api.outreach.io/api/v2/prospects/1
data
property will contain only the
found resource object instead of a list of resource objects.If a resource could not be found, the request will receive a 404 HTTP response with a descriptive JSON error message:
{
errors: [
{
id: "resourceNotFound",
title: "Resource Not Found",
detail: "Could not find 'prospect' with ID '1'.",
},
],
}
Include Related Resources
Sometimes when you retrieve a resource you want more than just a reference to its relationships, you want the full details of those relationships, too. With the Outreach API, you can easily specify which relationships to fully include within the request. Specify included resources in theinclude
query parameter; separate multiple resources by commas
and relationship-attribute pairs by periods.For example, to retrieve not just a individual prospect, but also its related stage and account, as well as its account's owner:
Request
GET https://api.outreach.io/api/v2/prospects/1?include=account.owner,stage
Response
{
data: {
type: "prospect",
id: 1,
attributes: {
firstName: "Sally",
lastName: null,
//...
},
relationships: {
account: {
data: {
type: "account",
id: 1,
},
},
stage: {
data: {
type: "stage",
id: 1,
},
},
//...
},
},
included: [
{
type: "account",
id: 1,
attributes: {
domain: "www.acme.example.com",
name: "Acme",
//...
},
relationships: {
//...
},
},
{
type: "stage",
id: 1,
attributes: {
name: "Initial",
order: 1,
//...
},
relationships: {
//...
},
},
{
type: "user",
id: 1,
attributes: {
email: "test-user@example.com",
//...
},
relationships: {
//...
},
},
],
}
Keeping the primary data separate from the list of included resources provides a better separation of concerns, and the final resource tree can be composed by referencing the included resource objects with the resource identifiers within relationships properties.
For more information, see Inclusion of Related Resources in the JSON API specification.Specify Sparse Fieldsets
By default, resource objects return all of their public attributes and relationships. But sometimes you're only interested in a few specific fields. In these cases you can specify sparse fieldsets by utilizing thefields
query
parameter.For example, to select only the prospect's first and last name, as well as the name of the account and stage:
Request
GET https://api.outreach.io/api/v2/prospects/1?include=account,stage&fields[account]=name&fields[prospect]=firstName,lastName&fields[stage]=name
Response
{
data: {
type: "prospect",
id: 1,
attributes: {
firstName: "Sally",
lastName: null,
},
},
included: [
{
type: "account",
id: 1,
attributes: {
name: "Acme",
},
},
{
type: "stage",
id: 1,
attributes: {
name: "Initial",
},
},
],
}
owner
is of type user
for
prospects), you will need to specify the resource type for sparse fieldsets.Request
GET https://api.outreach.io/api/v2/prospects/1?include=owner&fields[user]=firstName,lastName&fields[prospect]=firstName,lastName
Response
{
data: {
type: "prospect",
id: 1,
attributes: {
firstName: "Sally",
lastName: null,
},
},
included: [
{
type: "user",
id: 1,
attributes: {
firstName: "Amelia",
lastName: "Estevez",
},
},
],
}
Create a New Resource
You can create a new resource by making aPOST
request against the resource's collection path. The request body must
contain a JSON payload with a resource object as the primary data. Note that unlike in other circumstances, this
resource object must not contain an id
property.For example, to create a new prospect resource with a first name and to associated the new prospect with an existing account:
Request
POST https://api.outreach.io/api/v2/prospects
{
data: {
type: "prospect",
attributes: {
firstName: "John",
},
relationships: {
account: {
data: {
type: "account",
id: 1,
},
},
},
},
}
Response
{
data: {
type: "prospect",
id: 2,
attributes: {
firstName: "John",
lastName: null,
//...
},
relationships: {
account: {
data: {
type: "account",
id: 1,
},
},
//...
},
},
}
201
HTTP response with the same response body that you would
retrieve should you fetch the newly created resource again via its permanent URL.If there was a validation error and the request could not be completed, then the request will receive a 422
HTTP
response with a descriptive JSON error message:{
errors: [
{
id: "validationError",
title: "Validation Error",
detail: "Name can't be blank.",
source: {
pointer: "/data/attributes/name",
},
},
],
}
Update (May, 2023): In order to maintain the performance and reliability of our API services and allow modernization of our service architecture, Outreach has decided to remove support for including related objects on create/update operations.
Note that you can specify sparse fieldsets for create actions just like you can when fetching resources. However, if you want to include related objects you need an additional GET request.
Update an Existing Resource
You can update an existing resource by making aPATCH
request to the resource's path. The request body must contain a
JSON payload with a resource object as the primary data, and only present fields will be updated. The resource
object's type
and id
fields must be present and its ID must match the ID within the URL.For example, to update an existing prospect with a new first name and to remove the account relationship:
PATCH https://api.outreach.io/api/v2/prospects/1
{
data: {
type: "prospect",
id: 1,
attributes: {
firstName: "Sal",
},
relationships: {
account: {
data: null,
},
},
},
}
200
HTTP response with the same response body that you would
retrieve should you fetch the newly updated resource again via its permanent URL. If there was a validation error and
the request could not be completed, then the request will receive a 422
HTTP response with a descriptive JSON error
message.For more information, see Updating Resources in the JSON API specification.Update (May, 2023): In order to maintain the performance and reliability of our API services and allow modernization of our service architecture, Outreach has decided to remove support for including related objects on create/update operations.
Note that you can specify sparse fieldsets for create actions just like you can when fetching resources. However, if you want to include related objects you need an additional GET request.
Delete an Existing Resource
You can remove a resource by making aDELETE
request to the resource's path:DELETE https://api.outreach.io/api/v2/prospects/1
204
HTTP response with an empty response body. If there was
a validation error and the request could not be completed, then the request will receive a 422
HTTP response with a
descriptive JSON error message.For more information, see Deleting Resources in the JSON API specification.Other Actions on a Resource
Certain resources have further actions defined for individual items. These are accessed by making a request to a path like:
POST https://api.outreach.io/api/v2/tasks/1/actions/snooze
200
HTTP response with the body being the resource's response
body as if you had performed a GET
for that resource. If there was an error of some kind in performing the action, you
will receive a 422
HTTP response with a descriptive JSON error message.Some action requests have optional query parameters and/or required query parameters that influence how the action is performed:
POST https://api.outreach.io/api/v2/tasks/1/actions/markComplete?actionParams[completionNote]=I+completed+this
400
HTTP response being returned.Error Responses
When an error occurs, the response body's JSON payload will contain anerrors
property list instead of a data section.
Each error object will contain a unique id
and title
, as well as specific details
about this particular occurrence
of the error. Errors referencing specific fields will include a JSON source
pointer.For more information, see Error Objects in the JSON API specification.