# 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:


```json5
{
  errors: [
    {
      id: "unsupportedMediaType",
      title: "Unsupported Media Type",
      details: "Expected Content-Type header to be 'application/vnd.api+json'.",
    },
  ],
}
```

For more information, see JSON API content negotiation.

## Fetch a Collection of Resources

To fetch a collection of resources, make a `GET` 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](#error-responses) for more details.

p
Request

```txt
GET https://api.outreach.io/api/v2/prospects
```

p
Response

```json5
{
  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",
          },
        },
        //...
      },
    },
    //...
  ],
}
```

In this case of fetching a collection of resources, the data property will be a list of up to 50 resource objects. A *
*resource object** is a JSON object that contains at minimum the `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](/api/reference/) for more details.

### Filter by exact attribute


```txt
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.

Please consult the reference documentation for each relationship to see whether you can use filters like `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`.


```txt
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


```txt
GET https://api.outreach.io/api/v2/prospects?filter[firstName]=Sally&filter[account][name]=Acme
```

### Filter by a list of values


```txt
GET https://api.outreach.io/api/v2/prospects?filter[id]=1,2,3,5,8,13
```

### Filter by range of values


```txt
GET https://api.outreach.io/api/v2/prospects?filter[id]=5..10
```

### Filter by a less-than-or-equal-to condition


```txt
GET https://api.outreach.io/api/v2/prospects?filter[updatedAt]=neginf..2017-01-01
```

### Filter by greater-than-or-equal-to condition


```txt
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:


```txt
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


```txt
GET https://api.outreach.io/api/v2/prospects?sort=firstName
```

### Sort by descending attribute


```txt
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.


```txt
GET https://api.outreach.io/api/v2/prospects?sort=account.name // deprecated
```

### Sort by multiple criteria


```txt
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:


```txt
# 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
```

Instead of specifying a range with two dots, you instead use `[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:


```txt
# 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 provides `page` 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.


```txt
GET https://api.outreach.io/api/v2/prospects?page[size]=50&count=false
```

Along with the first 50 entries, the response contains a top-level `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.


```json5
{
  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-level `links` property to advance to next page.

To offset the page start:


```txt
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:


```txt
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-level `links` property that will
contain `first`, `prev`, `next` and `last` keys, if applicable. Use these links to easily navigate between slices of a
collection.

p
Request

```txt
GET https://api.outreach.io/api/v2/prospects?page[offset]=150
```

p
Response

```json5
{
  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 parameter `count`:


```txt
GET https://api.outreach.io/api/v2/prospects?filter[firstName]=Sally&count=true
```

If there are prospects named "Sally" there will be a first page of them returned in `data` property that is followed by `meta` containing total number of matching prospects:


```json5
{
    data: [
      //...
    ],
    meta: {
      count: 53,
      count_truncated: false
    },
    links: {
      //...
    }
}
```

In case there are no matching resources the response is short:


```json5
{
    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:


```json5
{
    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:


```json5
{
    data: [
      //...
    ],
    meta: {
        count: 0,
        count_truncated: true
    },
    links: {
        //...
    }
}
```

## Fetch an Individual Resource

You can fetch individual resources by making a `GET` request against any particular resource's pluralized type and ID
combination. For example, to retrieve an individual prospect resource:


```txt
GET https://api.outreach.io/api/v2/prospects/1
```

The response format will be the same as when fetching collections except that the `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:


```json5
{
  errors: [
    {
      id: "resourceNotFound",
      title: "Resource Not Found",
      detail: "Could not find 'prospect' with ID '1'.",
    },
  ],
}
```

For more information, see Fetching Resources in the JSON API
specification.

## 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 the `include` 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:

p
Request

```txt
GET https://api.outreach.io/api/v2/prospects/1?include=account.owner,stage
```

p
Response

```json5
{
  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 the `fields` query
parameter.

For example, to select only the prospect's first and last name, as well as the name of the account and stage:

p
Request

```txt
GET https://api.outreach.io/api/v2/prospects/1?include=account,stage&fields[account]=name&fields[prospect]=firstName,lastName&fields[stage]=name
```

p
Response

```json5
{
  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",
      },
    },
  ],
}
```

To request data about a relationship whose type does not match the relationship name (e.g. `owner` is of type `user` for
prospects), you will need to specify the resource type for sparse fieldsets.

p
Request

```txt
GET https://api.outreach.io/api/v2/prospects/1?include=owner&fields[user]=firstName,lastName&fields[prospect]=firstName,lastName
```

p
Response

```json5
{
  data: {
    type: "prospect",
    id: 1,
    attributes: {
      firstName: "Sally",
      lastName: null,
    },
  },
  included: [
    {
      type: "user",
      id: 1,
      attributes: {
        firstName: "Amelia",
        lastName: "Estevez",
      },
    },
  ],
}
```

For more information, see Fetching Sparse Fieldsets in the JSON API
specification.

## Create a New Resource

You can create a new resource by making a `POST` 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:

p
Request

```txt
POST https://api.outreach.io/api/v2/prospects
```


```json5
{
  data: {
    type: "prospect",
    attributes: {
      firstName: "John",
    },
    relationships: {
      account: {
        data: {
          type: "account",
          id: 1,
        },
      },
    },
  },
}
```

p
Response

```json5
{
  data: {
    type: "prospect",
    id: 2,
    attributes: {
      firstName: "John",
      lastName: null,
      //...
    },
    relationships: {
      account: {
        data: {
          type: "account",
          id: 1,
        },
      },
      //...
    },
  },
}
```

If the request was successful, the request will receive a `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:


```json5
{
  errors: [
    {
      id: "validationError",
      title: "Validation Error",
      detail: "Name can't be blank.",
      source: {
        pointer: "/data/attributes/name",
      },
    },
  ],
}
```

For more information, see Creating 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.

## Update an Existing Resource

You can update an existing resource by making a `PATCH` 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:


```txt
PATCH https://api.outreach.io/api/v2/prospects/1
```


```json5
{
  data: {
    type: "prospect",
    id: 1,
    attributes: {
      firstName: "Sal",
    },
    relationships: {
      account: {
        data: null,
      },
    },
  },
}
```

If the request was successful, the request will receive a `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 a `DELETE` request to the resource's path:


```txt
DELETE https://api.outreach.io/api/v2/prospects/1
```

If the request was successful, the request will receive a `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:


```txt
POST https://api.outreach.io/api/v2/tasks/1/actions/snooze
```

If the request is successful, the request will receive a `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:


```txt
POST https://api.outreach.io/api/v2/tasks/1/actions/markComplete?actionParams[completionNote]=I+completed+this
```

Providing additional, unacceptable parameters will result in a `400` HTTP response being returned.

## Error Responses

When an error occurs, the response body's JSON payload will contain an `errors` 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.