Clio Api v4 Documentation (v4)

Download OpenAPI specification:Download

E-mail: api@clio.com

Developer Support and Feedback

As we are all aware, the importance of API-level development is paramount in the cloud-based software industry. Clio’s open API allows you to create valuable add-ons for your clients, and in turn, construct profitable revenue streams for your business.

Please direct any inquiries to the appropriate channel:

A community driven Clio Developers Stack Overflow Group also exists where you can connect and ask questions from other Clio API users.

We look forward to seeing your creations and creating successful relationships!

Getting Started

The Clio API gives you and your approved developers secure access to the data in your Clio account. All Clio accounts, including free 7-day trial accounts, can be accessed using the documented Clio API. Learn how to make requests and receive data programmatically today (no need for lengthy signups or approvals).

The API is accessible in three geographic regions: the United States (app.clio.com), Canada (ca.app.clio.com) & Europe (eu.app.clio.com). These regions are distinct and do not share data. This document assumes the United States region is being used (app.clio.com), you should adapt the links and examples as necessary.

  • Start a 7-day free trial account using your development team’s email address & phone number at https://www.clio.com/getstarted
  • Login, create test data in the account, and then navigate to the developer application page to add a client application and generate an App Key & App Secret (details in the OAuth 2 section).
  • Use the App Key and App Secret to read & write data in your 7-day free trial account. Tools like Postman are an easy way to start testing.

When you are ready to build an app and integrate with Clio, start by upgrading your 7-day free trial account to an account that will not expire. Request an upgrade to a developer account by connecting with our partnerships team by providing the email used in your 7-day free trial in the intake form at https://www.clio.com/become-api-partner/

Please note that only accounts on a Boutique or Elite pricing plan can create apps or access applications not listed in the Clio Marketplace.

Authorization with OAuth 2.0

Create a Clio Application

  1. Login to your new Clio account at the login portal.
  2. Visit our developer portal.
  3. Click the Add button to create a new application. Enter details and select the scope of your application here - these details will be shown to Clio users when they're asked to authorize your application.
  4. Make note of the key and the secret, as these will be used to authorize your application with Clio.

This application holds the credentials you will use to authorize your users, so ensure you protect your Clio account!

Obtaining Authorization

These steps will guide you through the process of building the OAuth 2.0 workflow that your users will go through when authorizing your application. Each user will need to be authorized in this manner to connect their account in your application to their account in Clio.

Clio's API is only exposed through OAuth 2.0. In order to access any of the methods exposed in the API, your application must obtain authorization from the user.

Grant Type: Authorization Code

  1. Your application needs to make a request asking for authorization by including the following parameters and values.

    If you are building a desktop or mobile application, you may embed this request inside a WebView/WebBrowser control. As a desktop or mobile app does not have a web server to redirect to, your app may use https://app.clio.com/oauth/approval for your redirect_uri. This will place the code or error in both the URL and page title, which should be easily parsed out. Intercepting the request will vary from platform to platform. Here are some references to get you started:

    • .NET: WebBrowser event webbrowser.navigated.

    • OSX: webView:resource:didReceiveResponse:fromDataSource on the WebResourceLoadDelegate.

    • iOS: webView:shouldStartLoadWithRequest:navigationType on the UIWebViewDelegate.

    • Android: WebViewClient event onPageStarted (android.webkit.WebView, java.lang.String, android.graphics.Bitmap).

      Parameters:

      response_type:    code
      client_id:        application key from above
      redirect_uri:     callback URL to redirect to after authorization
      state (optional): Can be used by your application to maintain state between the request and the callback

      Request:

      GET /oauth/authorize?response_type=code&client_id=fzaXZvrLWZX747wQQRNuASeVCBxaXpJaPMDi7F96&redirect_uri=http%3A%2F%2Fyourapp.com%2Fcallback&state=xyz HTTP/1.1
      Host: app.clio.com

      Grant Approved:

      If the user grants your application access, Clio will redirect their browser to the callback url with an authorization code and any supplied state parameters. This code is only valid for 10 minutes.

      If you are building a desktop or mobile application, you will need to intercept the redirect to https://app.clio.com/oauth/approval inside your WebView/WebBrowser control and extract the code from the page's title. The title string will look like Success code=5IzZeWL2OmZUxGOGO4WE.

      Approved Redirect:

      http://yourapp.com/callback?code=s9jGYmL8E00ZyuJP3AEO&state=xyz

      Grant Declined:

      If the user declines your application access, Clio will redirect their browser to the callback url with an error parameter value of "access_denied".

      If you are building a desktop or mobile application, you will need to intercept the redirect to https://app.clio.com/oauth/approval inside your WebView/WebBrowser control and extract the error from the page's title. The title string will look like Failure error=access_denied.

      Declined Redirect:

      http://yourapp.com/callback?error=access_denied&state=xyz
  2. Your application may now make a POST request for an access token to Clio's token endpoint with the provided token. For Clio to verify the grant request, you must include your application's key and secret as well as the redirect_uri from the code request. Parameters:

    Parameters:

       client_id:     application key from above
       client_secret: application secret from above
       grant_type:    "authorization_code"
       code:          Authorization code from the redirect above
       redirect_uri:  Redirect URI used in the authorization request above

    Request:

       POST /oauth/token HTTP/1.1
       Host: app.clio.com
       Content-Type: application/x-www-form-urlencoded
    
       client_id=fzaXZvrLWZX747wQQRNuASeVCBxaXpJaPMDi7F96&client_secret=xVp5wAX05g1oDjV5astg2KZIZ85NX31FKTPV876v&grant_type=authorization_code&code=s9jGYmL8E00ZyuJP3AEO&redirect_uri=http%3A%2F%2Fyourapp.com%2Fcallback

    Response:

       HTTP/1.1 200 OK
       Content-Type: application/json
    
       {
         "token_type":"bearer",
         "access_token":"WjR8HLdo847Z8kdfUtewJpCvkRX4JYLCIF2dUUul",
         "expires_in":604800,
         "refresh_token":"5A0Ddf2RSt75v1VQcCoTB9rImRydF9yXA0gGvx7e"
       }
  3. Your application should save these tokens for future requests to the API. You should include an Authorization header with a value of Bearer access_token.

    See Oauth Refresh Tokens for more information on refresh tokens.

    Example Authorized Request:

     GET /api/v4/users/who_am_i HTTP/1.1
     Host: app.clio.com
     Authorization: Bearer WjR8HLdo847Z8kdfUtewJpCvkRX4JYLCIF2dUUul

    Example Ruby code for obtaining authorization with the authorization code grant type:

     require 'rubygems'
     require 'oauth2'
     client_key = 'Application key from https://app.clio.com/'
     client_secret = 'Application secret from https://app.clio.com/'
     client = OAuth2::Client.new(client_key, client_secret, :site => 'https://app.clio.com/')
    
     client.auth_code.authorize_url(:redirect_uri => 'http://yourapp.com/callback')
     # Redirect user or paste in the browser
     # => "https://app.clio.com/oauth/authorize?response_type=code&client_id=client_key&redirect_uri=http://yourapp.com/callback"
    
     # redirects to http://yourapp.com/callback?state=&code=secretcode
     # Use the code param below to get a token
    
     code = 'secretcode'
     token = client.auth_code.get_token(code, :redirect_uri => 'http://yourapp.com/callback')
     saved_token = token.token
     # => "WjR8HLdo847Z8kdfUtewJpCvkRX4JYLCIF2dUUul"
     saved_refresh_token = token.refresh_token
     # => "5A0Ddf2RSt75v1VQcCoTB9rImRydF9yXA0gGvx7e"
     # Save these values for future requests

    Example Ruby request:

     require 'rubygems'
     require 'oauth2'
    
     # Token saved from above
     saved_token = "WjR8HLdo847Z8kdfUtewJpCvkRX4JYLCIF2dUUul"
    
     client_key = 'Application key from https://app.clio.com/'
     client_secret = 'Application secret from https://app.clio.com/'
     client = OAuth2::Client.new(client_key, client_secret, :site => 'https://app.clio.com/')
    
     token = OAuth2::AccessToken.new(client, saved_token)
    
     response = token.get('/api/v4/users/who_am_i', params: {fields: 'id,name,last_name,first_name,email,enabled,account_owner'})
     response.class.name
     # => OAuth2::Response
     response.body
     # => "{\"data\":{\"id\":1,\"name\":\"Demo User\",\"first_name\":\"Demo\",\"last_name\":\"User\",\"email\":\"demo@clio.com\",\"enabled\":true,\"account_owner\":true}}"

Deauthorization

Deauthorization can happen in one of two ways: the user has revoked access to your application, or your application has requested to be deauthorized. When a user revokes access to your application, ALL access tokens will be revoked. If your application requests to be deauthorized, only the supplied access token will be revoked.

In both cases Clio will make a POST request to your application's deauthorization callback URL (if present). The callback will include a JSON object containing the client_id, user_id and the access_token (set to "all" if user revoked).

Deauthorization Callback Request:

POST /deauthorization_callback HTTP/1.1
Host: yourapp.com
Content-Type: application/json

{
  "client_id": "fzaXZvrLWZX747wQQRNuASeVCBxaXpJaPMDi7F96",
  "user_id": 2332,
  "access_token": "all"
}

For your application to deauthorize itself, you need to make an authorized POST request to /oauth/deauthorize. Clio's response should be a simple 200 status code.

Parameters:

token:         token to be revoked

Request:

POST /oauth/deauthorize HTTP/1.1
Host: app.clio.com
Authorization: Bearer WjR8HLdo847Z8kdfUtewJpCvkRX4JYLCIF2dUUul

token=WjR8HLdo847Z8kdfUtewJpCvkRX4JYLCIF2dUUul

Response:

HTTP/1.1 200 OK

Oauth Refresh Tokens

For background on refresh tokens, see Understanding Refresh Tokens.

When the user grants access to your application, you receive both an access token and a refresh token. The access token has a limited lifespan and will eventually expire. Once it expires, you can use your refresh token to refresh your access.

Checking Expiry:

Your access token has a limited lifespan. When you initially receive your access token, you also get back the token's lifespan, in seconds. Most Oauth libraries support checking to see if your token has expired.

Example Ruby code:

# Token obtained above
token.expired?
# => false
token.expires_in
# => 604770

Refreshing Access:

If your access token has expired, you can refresh your access. You use your refresh token with the grant_type: "refresh_token".

Note: The refresh_token parameter will only be returned if the refresh token changes from the original. Refresh tokens are typically long-lasting credentials.

Parameters:

  client_id:     application key from above
  client_secret: application secret from above
  grant_type:    "refresh_token"
  refresh_token: Refresh token code from above

Request:

  POST /oauth/token HTTP/1.1
  Host: app.clio.com
  Content-Type: application/x-www-form-urlencoded

  client_id=fzaXZvrLWZX747wQQRNuASeVCBxaXpJaPMDi7F96&client_secret=xVp5wAX05g1oDjV5astg2KZIZ85NX31FKTPV876v&grant_type=refresh_token&refresh_token=5A0Ddf2RSt75v1VQcCoTB9rImRydF9yXA0gGvx7e

Response:

  HTTP/1.1 200 OK
  Content-Type: application/json

  {
    "token_type":"bearer",
    "access_token":"rFlGXgfqh1e8yBIGGh4jSMaJAuOZb4Bo4VKEG6wK",
    "expires_in":604800,
    "refresh_token":"5A0Ddf2RSt75v1VQcCoTB9rImRydF9yXA0gGvx7e"
  }

Example Ruby request:

require 'rubygems'
require 'oauth2'
# Obtain token as described above.
if token.expired?
  token = token.refresh! # Uses token.refresh_token value
  # Save the new access token for future requests.
end

Secure Your Refresh Token:

Unlike the access token, your refresh token does not expire. You must ensure these tokens are securely stored and encrypted.

Oauth Scopes

For background on Oauth scopes, see Oauth.com's article.

If you are writing an application which deals with tasks, you probably do not need access to bills or matters. Oauth scopes are a way to limit your access to the user’s account.

When a user is prompted to authorize your application, they are presented with a list of Oauth scopes you are requesting, along with information on each scope. If they accept this list of scopes, they grant access. From then on, your application is restricted to only those scopes, for that user.

You can select your list of scopes when you create your client application. For example, perhaps you need read access to contacts, read/write access to matters, and read access to users. Remember, the users will see each scope you are requesting, so you must choose the smallest set necessary for your application to function properly. The full list of available scopes is visible when you create a new client application.

You may change your set of scopes at any time, but once a user has authorized your application, their scopes are fixed. If you subsequently need additional access, users will have to reauthorize your application.

Read access allows you to read information for that endpoint. For example, read access to matters allows you to get a list of matters, or get detailed information about a specific matter. It also allows you access to related endpoints. Our documentation shows that matters, relationships, notes, practice areas, and log entries are all related. Read access to matters allows you read access to any of these related endpoints.

Write access allows you to create, update, or destroy information for that endpoint. For example, write access to matters allows you to create a new matter, update an existing matter, or destroy a matter. Similarly, you get write access to all related endpoints.

If you try to access an endpoint without the necessary scopes, you receive error code 403 - Forbidden.

Response:

HTTP/1.1 403 Forbidden

{
  "error":{
    "type":"ForbiddenError",
    "message":"User is forbidden from taking that action"
  }
}

Be careful with nested fields! If you have read access to matters and read access to contacts, you can request information about a matter and its associated client, as follows: 'id,display_number,client{id,name}'

Request:

GET /api/v4/matters/1?fields=id,display_number,client{id,name} HTTP/1.1
Host: yourapp.com
Content-Type: application/json

{
  "data": {
    "id":1,
    "display_number":"00001-Marquardt-Walter",
    "client":{
      "id":1,
      "name":"Marquardt-Walter"
    }
  }
}

If on the other hand, you have read access to matters but do not have read access to contacts, we will only display the client's id; all other information about the contact will be redacted.

Request:

GET /api/v4/matters/1?fields=id,display_number,client{id,name} HTTP/1.1
Host: yourapp.com
Content-Type: application/json

{
  "data": {
    "id":1,
    "display_number":"00001-Marquardt-Walter",
    "client":{
      "id":1,
      "redacted":true
    }
  }
}

Here is some Ruby code demonstrating these concepts.

require 'rubygems'
require 'oauth2'

client_key = 'SUNLAvcBLRpm58ifRJONr9pNyTznoUcvLCwA451y' # Your own value here
client_secret = '0TkElPVV7ZBBPoY9jC3aZ6ucfxbORRcSqLewLnMG' # And here
client = OAuth2::Client.new(client_key, client_secret, :site => 'https://app.clio.com/')
token = OAuth2::AccessToken.new(client, saved_token) # saved_token is stored in your database

# Now, let's assume you have read access to users, matters, and contacts.
# This works, because you have read access to users.
puts token.get('/api/v4/users/who_am_i').body
# => {"data":{"etag":"\"93027c76885d9b2da02cf90713aedc78\"","id":1,"name":"Demo User"}}

# This works, because you have read access to matters.
puts token.get('/api/v4/matters').body
# => {"data":[{"id":1,"etag":"\"beea69c32b8f86d3afb2ef8808a9ba00\"","display_number":"00001-Luettgen, Marks and Wilkinson"},{"id":2,"etag":"\"fb6d3a8bc51f7c34ed198222201f2eae\"","display_number":"00002-Cummings and Sons"},{"id":3,"etag":"\"7459639645818d811a6b77a76d26934d\"","display_number":"00003-Rogahn, Fritsch and Homenick"}],"meta":{"paging":{},"records":3}}

# This works, because you have read access to matters and to contacts.
puts token.get('/api/v4/matters/1', params: {fields: 'id,etag,display_number,description,client{id,first_name,last_name,name}'}).body
# => {"data":{"id":1,"etag":"\"beea69c32b8f86d3afb2ef8808a9ba00\"","display_number":"00001-Luettgen, Marks and Wilkinson","description":"In eveniet exercitationem et.","client":{"id":1,"name":"Luettgen, Marks and Wilkinson"}}}


# Now, let's assume you have read access to matters, but no access to contacts or users.
puts token.get('/api/v4/contacts').body
# => {"error":{"type":"ForbiddenError","message":"User is forbidden from taking that action"}}
# The response code is 403 - Forbidden

# This doesn't work either; you don't have read access to users.
puts token.get('/api/v4/users/who_am_i').body
# => {"error":{"type":"ForbiddenError","message":"User is forbidden from taking that action"}}

# Let's try to get information about contacts, via matters:
puts token.get('/api/v4/matters/1', params: {fields: 'id,etag,display_number,description,client{id,first_name,last_name,name}'}).body
# => {"data":{"id":1,"etag":"\"beea69c32b8f86d3afb2ef8808a9ba00\"","display_number":"00001-Luettgen, Marks and Wilkinson","description":"In eveniet exercitationem et.","client":{"id":1,"redacted":true}}}
# Note that all information about the client other than the id is redacted.

Permissions

Some objects in Clio are protected via permissions. This could be due to insufficient Oauth scope permissions, or from the role permissions inside Clio. If associated data is protected in this fashion, we will remove requested fields, and add a redacted boolean field onto the object. This field may be requested just like any others, but it will automatically be added if we have redacted the object.

For example, if the user does not have the Billing permission, or if the user has not granted the Clio application the ability to read bills, you may have a response similar to:

GET /api/v4/activities/15?fields=id,bills{id,number} HTTP/1.1
Host: yourapp.com
Content-Type: application/json

{
  "data": {
    "id": 15, "bill": { "id": 527, "redacted": true}
  }
}

Matters

If the protected data is a matter, the response will behave as stated above, with the exception that the matter's display_number will be included in the response if requested. For example, consider a task with an associated matter that the user does not have permission to access:

GET /api/v4/tasks/16?fields=id,matter{id,display_number,client} HTTP/1.1
Host: yourapp.com
Content-Type: application/json

{
  "data": {
    "id": 16, "matter": { "id": 1, "display_number": "00001-Luettgen, Marks and Wilkinson", "redacted": true}
  }
}

Activities

In version 4.0.5, if the activity is of type TimeEntry and the user has a rate visibility of limited or none, the response will show everything that is requested, with the exception that the price and total may be redacted:

GET /api/v4/activities?fields=id,quantity,price,total HTTP/1.1
Host: yourapp.com
Content-Type: application/json

{
  "data": {
    "id": 16, "quantity": 2197, "redacted": true
  }
}

If the user’s rate visibility is set to limited, both the price and total of the time entries that other users have created are removed from the response and the attribute redacted is set as true to indicate the hidden information. If the user’s rate visibility is set to none, both the price and total of all time entries are removed from the response and the attribute redacted is set as true to indicate the hidden information.

Fields

By default only the fields id and etag are returned as part of the response. Each request may specify which fields it wants to receive as a comma separated list on the fields parameter. For example: fields=id,etag. Nested resources will return the resource's default fields. To change this behavior, other fields from nested resources can be requested by placing a comma separated list inside {, }. For example: fields=id,etag,nested_resource{id,name}. If a field is invalid, a 400 Bad Request will be returned.

Rate Limiting

Requests to API v4 are rate-limited by OAuth token. This means that after a certain number of requests in a given time period, the API will return a 429 Too Many Requests response. Regular responses will include two headers: X-RateLimit-Limit (the number of allowed requests in a time period) and X-RateLimit-Remaining (the number of remaining requests in the time period)

If the limit is exceeded a Retry-After header will be supplied with the number of seconds to wait until the request should be tried again.

Certain endpoints have custom rate limits. See specific endpoint documentation for further information.

Paging

Index actions are limited to 200 resources unless otherwise specified. A limit parameter may be supplied to lower this limit. An offset parameter may be supplied to skip records. Metadata about paging is returned in the index actions: { data: { ... }, meta: { paging: { previous: '', next: '' } }, }

The previous and next fields will be URLs for the previous and next page of data, respectively. If there is no previous or next page, the field will be missing.

There is a limit to the number of resources that can be requested through pagination so if you are expecting a large data set, we recommend using Bulk Actions. If you attempt to retrieve a page over the limit, you will receive a 422 ArgumentError.

ETags

For single resources we return ETag and Last-Modified HTTP headers. etag is also a field on most resources that can be returned via index actions. If you supply an If-None-Match or If-Modified-Since header with the values of the resource's ETag or Last-Modified field, respectively, the API will return a 304 Not Modified response.

Optimistic Concurrency Control

For PATCH requests, if you supply an If-Match header with the resource's ETag value, the request will support optimistic concurrency control. That is, if the ETag value passed in the header matches the value of the resource's ETag, it means that you have the latest version of the resource and are safe to update without worrying about overwriting someone's changes (Lost Update Problem).

If it is not the correct value, it means that the resource has changed since you last retrieved it and there might be changes you would overwrite, so it will return a 412 Precondition Failed. To remedy this, retrieve the resource that you're trying to update again and see if there are new changes and decide what you want to do with them. Note the ETag value and pass that back into the header and perform the update again. It should return a 200 OK now.

Minor Versions

API v4 may have multiple minor versions. Versions are of the form '4.X.Y'. Optionally a X-API-VERSION header may be supplied to keep specific behavior. If this header is omitted, it will default to the latest version. An X-API-VERSION will be included in all successful responses with the version that is being used. If the header is present but invalid, it will return a 410 Gone response. If the header is present and valid, but it is no longer supported, it will return a 410 Gone response.

  • 4.0.4

    Update quantity field to return values in seconds rather than hours for Activities

    This is the current version

Model Events (Beta)

Certain endpoints support model events. (See Example below)

This endpoint can be used to get a list of objects that have changed. This feature is useful for integrations that need to sync a full data set from Clio. To set up Model Events for a particular endpoint:

1) Make a List Bulk Action request with the X-Events header set to true. The response will contain a header named X-Events-Page-Token that will be used to fetch events for a model.

2) Make a request to the /:model/events endpoint for the model with a query parameter page_token equal to the X-Events-Page-Token from the previous request. You may also provide a fields parameter to gather additional data, however the id and events will always be included.

The response will contain a new X-Events-Page-Token value that you can use for the next request. Records that have been deleted, or had permissions revoked to the developer application's user will appear in the listing, but all information outside of the id and events fields will be redacted. If you receive a response which contains fewer than the maximum of 200 changed objects, your sync is all caught up to the present.

Example:

To set up the event stream for matters:

    **Request**:
      X-Bulk: true
      X-Events: true
      GET /api/v4/matters.json?fields=id,display_name

    **Response**:
      X-Bulk-Action-id: 123
      X-Events-Page-Token: c17d6abc-0df9-4de4-b68d-2e9df23ef419
      202 Accepted

To fetch the changed events with the page_token:

    **Request**:
      GET /api/v4/matters/events?fields=id,display_number&page_token=c17d6abc-0df9-4de4-b68d-2e9df23ef419

    **Response**:
      X-Events-Page-Token: 9e1df0c8-b661-461e-9c64-c2c3e829e600
      {
        data: [
          {
            record: {id: 1, display_number: "foo"},
            events: [
              { event_type: "created", time: "2018-04-26T20:09:00Z" },
              { event_type: "updated", time: "2018-04-27T02:52:00Z" }
            ]
          },
          {
            record: {id: 2, display_number: "bar"},
            events: [
              { event_type: "granted", time: "2018-04-23T17:37:00Z" }
           ]
          },
          {
            record: {id: 3, redacted: true},
            events: [
              { event_type: "revoked", time: "2018-04-26T11:41:00Z" }
            ]
          },
          {
            record: {id: 4, redacted: true},
            events: [
              { event_type: "updated", time: "2018-04-21T10:01:00Z" },
              { event_type: "deleted", time: "2018-04-22T10:02:00Z" }
            ]
          }
        ]
      }

Token Expiry

If the page token expires, the endpoint will return a 410 Gone and the process needs to be started again. However note that the fields of the bulk action are not relevant to the event stream creation, so a Bulk listing with fields=id and the proper headers will be enough to setup the events and tokens again.

Tokens can be reused, but will expire under one of the conditions below:

1) 7 days has passed since token creation.

2) The developer application user's permissions have significantly changed. This could be in the form role changes, or gaining/losing permission groups.

3) The OAuth scopes for the developer application have changed.

Bulk Actions

API v4 will allow bulk actions for most endpoints. To use bulk actions:

  1. Make a request to the action with an X-BULK header with the value true. The response will always be a 202 Accepted.
  2. Poll the URL provided in the Location header of the response. This URL is for the Bulk Actions endpoint.
  3. Once the action is complete, polling the URL will return a 303 See Other response.
  4. Download the response from URL in the Location header of the 303 See other response.

Note:

  • For some bulk actions the parameter format may change slightly.
  • Clio only permits one active bulk action request per endpoint per OAuth token.

Authorization note: The Authorization header & token used to access the API should not be used when downloading the response from the URL in the Location header of the 303. Doing so will result in a 400 error being returned. The URL provided for download is a signed URL and does not require additional authorization.

List

The primary use case of using Bulk Actions for a listing endpoint is to remove the need for paging. This is useful if you require a full list of records for situations such as: syncing a full set of data, or creating a report based off the fields and request parameters.

The limit, and the page_token parameters are ignored, otherwise the request parameters are the same as a non-bulk request. The eventual response that is received from step 4 above might look something like:

  {
     data: [
       { status: 200, data: [ { id: 1 }, { id: 2 } ] }
     ]
     status: 'completed', requested: 1, performed: 1
  }

Create

The request parameter format changes slightly for this action. Using contacts as an example, creating multiple records would look something like:

Request
  POST /api/v4/contacts.json
  {
    data: [
       { first_name: "Foo", type: "Person" },
       { type: "Person" }
    ],
    fields: "id,first_name"
  }

Eventual Response
  {
     data: [
       { status: 200, data: { id: 1, first_name: "Foo" } },
       { status: 422, error: { message: "At least one of first name or last name must be provided", type: "RecordInvalid" } },
     ],
     status: 'completed', requested: 2, performed: 2
  }

Update

The request parameter format changes slightly for this action. Using contacts as an example, updating multiple records would look something like:

Request
  PATCH /api/v4/contacts.json
  {
    data: [
       { id: 1, first_name: "Foo" },
       { id: 2, type: "Invalid" }
    ],
    fields: "id,first_name"
  }

Eventual Response
  {
    data: [
       { status: 200, data: { id: 1, first_name: "Foo" } },
       { status: 400, error: { message: "type must be one of the follow: 'Company', or 'Person'", type: "ArgumentError" } },
    ],
    status: 'completed', requested: 2, performed: 2
  }

Destroy

The request parameter format changes slightly for this action. Using contacts as an example, destroying multiple records would look something like:

Request
  DELETE /api/v4/contacts.json
  {
    data: [
       { id: 1 },
       { id: 2 }
    ]
  }

Eventual Response
  {
     data: [
       { status: 202 },
       { status: 202 },
     ],
     status: 'completed', requested: 2, performed: 2
  }

Update a single BulkAction

Outlines the parameters and data fields used when updating a single BulkAction

path Parameters
id
required
integer <int32>

The unique identifier for the BulkAction.

query Parameters
fields
string

The fields to be returned. See response samples for what fields are available. For more information see the fields section.

header Parameters
IF-MATCH
string

The server will update the requested resource and send back a 200 status, but only if value in the header matches the existing resource's ETag.

X-API-VERSION
string

The API minor version. Default: latest version.

Request Body schema:
data
required
object

Responses

200

Ok

400

Bad Request

401

Unauthorized

403

Forbidden

404

Not Found

412

Precondition Failed

422

Unprocessable Entity

429

Too Many Requests

patch /bulk_actions.json
/api/v4/bulk_actions.json

Request samples

No sample

Response samples

application/json
Copy
Expand all Collapse all
{
  • "data":
    {
    }
}