Requests and Responses

URI Parameters

API routes can contain URI parameters, that when defined, are always required.

Each URI parameter used in a route is defined within curly braces: {uri_param_name: uri_param_type}.

All possible values for uri_param_type are listed below:

  • int - integer

  • str - string

  • b32 - base32 encoded utf-8 string

  • uuid - UUID

Examples:

/v3/users/{user_id: int}
/v3/products/{adspert_product_id: str}/converting-criteria

Details about a particular route can be found in our detailed routes documentation.

Query Parameters

Query parameters accepted on a particular route are specified in the detailed routes documentation. This section describes standard query parameters which are used on various routes.

Field Selection

The query parameters include and exclude may specify one or multiple fields from the response data to include or exclude in the response. References may be nested using a dot notation.

If a route’s response data by default looks like

[
  {"user": {"id": 210, "name": "Sue"}, "team": {"id": 938, "name": "Engineers"}},
  {"user": {"id": 722, "name": "Joe"}, "team": {"id": 217, "name": "Medical"}}
]

then the the query parameters include=user&exclude=user.id&include=team.id would reduce the response data to:

[
  {"user": {"name": "Sue"}, "team": {"id": 938}},
  {"user": {"name": "Joe"}, "team": {"id": 217}}
]

Note: No matter if the data structure contains single objects or object arrays, the path is the same. This means it is not possible to reference an index in an array, only object fields.

Sorting

On routes where the response data is a collection and has sortable fields, field-specific sort query params may be used to sort results. The query parameters are named like sort_{response_field_name}, for instance sort_user_id, and must have an integer value.

The absolute value of the number specifies the field’s sort priority in case of multi-field sorting (lower absolute number means higher priority). Negative numbers express a descending sort.

For instance the query parameters sort_user_id=-2&sort_user_name=1 would mean that the response data is first sorted ascending by user names and all users with the same name are sorted descending by the user ID.

Filtering

On routes where the response data is a collection and has filterable fields, field-specific filter query params may be used to reduce the result set. The query parameters are named like filter_{response_field_name} and must contain an array of values to filter for.

For instance the query param filter_user_id=22,88 would limit results to users with the IDs 22 and 88. If there are filter query params for multiple fields, the response contains only objects where all filters match.

Response Enveloping

General

All responses share a common structure in the response data:

{
  "status": 200,
  "message": "OK",
}

These fields mirror the HTTP response status with the exception that the message might contain additional information:

{
  "status": 400,
  "message": "Bad Request: Endpoint does not accept query parameters."
}

Successful Requests

Response data for successful requests (e.g. 200 OK or 201 Created) has 2 additional fields: data and meta:

{
  "status": 200,
  "message": "OK",
  "data": {
    "...": "...",
  },
  "meta": {
    "...": "..."
  }
}

The data field may be a single object, an array of objects, or null (in case a route does not provide any response data).

The meta field provides additional information about the response data, for instance pagination information:

{
  "status": 200,
  "message": "OK",
  "data": [{"...": "..."}, {"...": "..."}],
  "meta": {
    "pagination": {
      "offset": 0,
      "limit": 2,
      "total": 10,
      "sort": {
        "thing": 1
      }
    }
  }
}

Validation Errors

If input data validation failed, the response status code is 422 Unprocessable Entity and the response data has this structure:

{
  "status": 422,
  "message": "Unprocessable Entity: Input data validation failed.",
  "errors": [
    {
      "path": ["path to a request data element using index and field names"],
      "message": "What's wrong with that particular data element"
    }
  ]
}

Consider a route which accepts the PATCH method where request data must be an array of objects to patch (bulk update). The response data:

{
  "status": 422,
  "message": "Unprocessable Entity: Input data validation failed.",
  "errors": [
    {
      "path": [1, "user", "id"],
      "message": "Not a valid integer."
    },
    {
      "path": [3, "user", "name"],
      "message": "Missing required field."
    }
  ]
}

would indicate that 2 of the provided objects had problems. The one with index 1 did not provide a valid user ID. The object at index 3 misses a user name.

Other Errors

All other errors (e.g. 400 Bad Request and 500 Internal Server Error) have a very basic response body:

{
  "status": 400,
  "message": "Bad Request: Endpoint does not accept query parameters."
}

{
  "status": 500,
  "message": "Internal Server Error: Alien attack."
}

Media Types

By default the API expects request data and returns response data as JSON. However, if a data schema allows it, CSV and Excel are also supported.

Errors are Always JSON

For data resources error responses are always encoded as JSON. The reason is that tabular media types like CSV or Excel are not well suited to represent structured error responses.

Meta Data in Response Headers

For tabular media types like CSV or Excel the meta information normally provided in JSON response envelopes (see above) are provided in response headers instead. See the the examples below for details.

CSV

Request Data

Set the Content-Type header to text/csv; charset=UTF-8 if you want to provide request data in CSV format:

http

PATCH /v3/accounts/1234/campaigns HTTP/1.1
Host: api.adspert.net
Content-Type: text/csv; charset=UTF-8
Authorization: Bearer 433126ffa47f453c21f26d9f15ea11f5...

campaign_id,conversion_value
928392811,5000000
140447453,8000000
992896011,6500000

curl

curl -i -X PATCH https://api.adspert.net/v3/accounts/1234/campaigns -H "Content-Type: text/csv; charset=UTF-8" -H "Authorization: Bearer 433126ffa47f453c21f26d9f15ea11f5..." --data-raw 'campaign_id,conversion_value

928392811,5000000

140447453,8000000

992896011,6500000'

httpie

echo 'campaign_id,conversion_value

928392811,5000000

140447453,8000000

992896011,6500000' | http PATCH https://api.adspert.net/v3/accounts/1234/campaigns Content-Type:"text/csv; charset=UTF-8" Authorization:"Bearer 433126ffa47f453c21f26d9f15ea11f5..."

python-requests

requests.patch('https://api.adspert.net/v3/accounts/1234/campaigns', headers={'Content-Type': 'text/csv; charset=UTF-8', 'Authorization': 'Bearer 433126ffa47f453c21f26d9f15ea11f5...'}, data='campaign_id,conversion_value\r\n\n928392811,5000000\r\n\n140447453,8000000\r\n\n992896011,6500000')

response

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8

{
  "status": 200,
  "message": "OK",
  "data": null,
  "meta": {}
}

The provided CSV text should follow RFC 4180. In particular the following hard requirements apply:

  • Columns are comma separated.

  • Values which contain a comma must be quoted (A, B => "A, B").

  • Quotes in values must be represented as double quotes (A "quote" => "A ""quote""").

Response Data

Set the Accept header to text/csv to request response data in CSV format:

http

GET /v3/accounts/1234/campaigns?include=campaign_id&include=campaign_name&include=status&limit=3&sort_campaign_id=-2&sort_status=1 HTTP/1.1
Host: api.adspert.net
Accept: text/csv
Authorization: Bearer 433126ffa47f453c21f26d9f15ea11f5...

curl

curl -i -X GET 'https://api.adspert.net/v3/accounts/1234/campaigns?include=campaign_id&include=campaign_name&include=status&limit=3&sort_campaign_id=-2&sort_status=1' -H "Accept: text/csv" -H "Authorization: Bearer 433126ffa47f453c21f26d9f15ea11f5..."

httpie

http 'https://api.adspert.net/v3/accounts/1234/campaigns?include=campaign_id&include=campaign_name&include=status&limit=3&sort_campaign_id=-2&sort_status=1' Accept:text/csv Authorization:"Bearer 433126ffa47f453c21f26d9f15ea11f5..."

python-requests

requests.get('https://api.adspert.net/v3/accounts/1234/campaigns?include=campaign_id&include=campaign_name&include=status&limit=3&sort_campaign_id=-2&sort_status=1', headers={'Accept': 'text/csv', 'Authorization': 'Bearer 433126ffa47f453c21f26d9f15ea11f5...'})

response

HTTP/1.1 200 OK
Content-Type: text/csv; charset=UTF-8
Content-Disposition: attachment; filename="campaigns.1-to-3-of-28.csv"
X-Adspert-Pagination-Offset: 0
X-Adspert-Pagination-Limit: 3
X-Adspert-Pagination-Total: 28
X-Adspert-Pagination-Sort: campaign_id=-2,status=1

"campaign_id","campaign_name","status"
928392811,"pariatur vehicula","ACTIVE"
140447453,"tucan elit","ACTIVE"
992896011,"dolor gereva","PAUSED"

The CSV dialect follows RFC 4180:

  • CRLF is used to separate rows.

  • A comma is used to separate columns.

  • Values are quoted when needed: When they contain a comma, a line break or a quote itself. The latter is represented as a double quote. For instance Value "with" quote, and comma will be represented as "Value ""with"" quote, and comma".

Human Readable Values

When using the header X-Adspert-CSV-Humanize, some values in the returned CSV data are converted to a more human friendly format. In particular:

  • Monetary values are provided as decimal values instead of micros, along with a currency: 1230000 => EUR 1.23.

  • The value of a field which represents a ratio is converted to a corresponding percentage value: 0.12 => 12 %.

  • Date-time values are represented as YYYY-MM-DD HH:MM:SS TIMEZONE: 2020-02-18T14:21:51.142120+00:00 => 2020-02-18 14:21:51 UTC.

The header value must be either TRUE or FALSE.

Custom Column Names

The column names in the returned CSV can be adjusted using the header X-Adspert-Table-Columns. If this header is used, the query param include is mandatory and its values must align with the custom column names, for instance:

  • Query param: include=campaign_id&include=campaign_name&include=status

  • Header: X-Adspert-Table-Columns: ID,Name,Status

Excel

This is only supported for response data!

Set the Accept header to application/vnd.openxmlformats-officedocument.spreadsheetml.sheet to request response data in CSV format:

http

GET /v3/accounts/1234/campaigns?include=campaign_id&include=campaign_name&include=status&limit=3&sort_campaign_id=-2&sort_status=1 HTTP/1.1
Host: api.adspert.net
Accept: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Authorization: Bearer 433126ffa47f453c21f26d9f15ea11f5...
X-Adspert-Table-Columns: ID,Name,Status

curl

curl -i -X GET 'https://api.adspert.net/v3/accounts/1234/campaigns?include=campaign_id&include=campaign_name&include=status&limit=3&sort_campaign_id=-2&sort_status=1' -H "Accept: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" -H "X-Adspert-Table-Columns: ID,Name,Status" -H "Authorization: Bearer 433126ffa47f453c21f26d9f15ea11f5..."

httpie

http 'https://api.adspert.net/v3/accounts/1234/campaigns?include=campaign_id&include=campaign_name&include=status&limit=3&sort_campaign_id=-2&sort_status=1' Accept:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" X-Adspert-Table-Columns:ID,Name,Status Authorization:"Bearer 433126ffa47f453c21f26d9f15ea11f5..."

python-requests

requests.get('https://api.adspert.net/v3/accounts/1234/campaigns?include=campaign_id&include=campaign_name&include=status&limit=3&sort_campaign_id=-2&sort_status=1', headers={'Accept': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'X-Adspert-Table-Columns': 'ID,Name,Status', 'Authorization': 'Bearer 433126ffa47f453c21f26d9f15ea11f5...'})

response

HTTP/1.1 200 OK
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=UTF-8
Content-Disposition: attachment; filename="campaigns.1-to-3-of-28.xlsx"
X-Adspert-Pagination-Offset: 0
X-Adspert-Pagination-Limit: 3
X-Adspert-Pagination-Total: 28
X-Adspert-Pagination-Sort: campaign_id=-2,status=1

... XLSX file data ...

Human Readable Values

Because Excel files are primarily processed by humans, the “humanize” behavior described above for CSV is the default for Excel response data.

This makes use of Excel’s number formatting, i.e. values are nevertheless stored as numeric values.

Custom Column Names

Column names can be customized the same way as for CSV responses.