logo

Developer Cookbook

Common interactions with the API


The recipes below are examples calling Caseblocks from an external system.

The same examples can be executed from inside Caseblocks using the provided scripting environment, but we make high-level libraries available for the scripting environment that will abstract the GraphQL and reduce the lines of code.

Finding a specific case

To retrieve a specific case all you need to know is the ID of that case, which you can retrieve using some of the search and bucket retrieval examples below.

Assuming you know the ID, eg. id: 36368, fetching a case is simple:

query {
  case(caseId: 36368, ignoreTimeline: true) {
    id
    title
    currentState
    caseTypeId
    caseType
    properties
    fileAttachments {
      url
    } 
  }
}

The example above retrieves the case's title and current state, as well as the bag of properties that contain the fields referenced in the case template schema. The example also shows us retrieving any file attachment URLs associated with the case.

The ignoreTimeline: true parameter is optional and defaults to false. Setting the flag to true will cause Caseblocks not to record the retrieval in the case's timeline. By default all retrievals are recorded as view-events.

Besides fetching properties and file attachments, you can also retrieve the following:

  • task history
  • current viewers
  • notes
  • conversations

More information is available in API reference.

Updating a case

To update a case you need to its ID, for example id: 36368.

mutation {
  updateCase(updatedCase: {
    id: 36368,
    title: "Claim 2020-00012",
    currentState: "Pending",
    properties: {
      claim_amount: 1200
    }
  }) {
    error
    message
    lowLevelErrorMessage
    case {
      id
      updatedAt
    }
  }
}

Besides the id, you need to specify title, currentState even if these values haven't changed. The properies bag needs to be the full list of fields defined in the schema, not just the fields that you're updating.

The mutation above shows us returning error, message, and lowLevelMessage to allow us to determine success or failure. We're also retrieving the case id and updatedAt fields.

More information is available in API reference.

Creating a new case

Here's a GraphQL mutation to create a new Claim:

mutation {
  createCase(newCase: {
    title: "Claim 123",
    currentState: "Awaiting Assessment",
    caseTypeCode: "claim",
    properties: {
      claim_date: "2020-05-07T00:00:00",
      claim_value: 3150,
      claim_source: "website",
      broker_claim: false
    }
  }) {
    error
    message
    lowLevelErrorMessage
    caseData
  }
}

In the mutation example above we're calling the createCase(...) mutation. We're required to specify title, currentState, caseTypeCode, and a bag of properties which contain fields specified in the schema for the Claim case type. Each entry in the bag of properties is strongly-typed using ISO8601 dates, numbers, strings, and boolean values. Caseblocks will in return an error flag, a set of messages, and the caseData of the newly created case if the mutation has been successful.

More information is available in API reference.

To execute a search that behaves like the Global Search feature in the GUI execute the following query

query {
  globalSearch(searchTerm: "time") {
    error
    results {
      caseTypeId
      cases {
        title
        currentState
      }
      total
    }
  }
}

In the example above we're searching for cases that contain the word time in any of the fields defined in any of the case templates. For each case we're returning the title, and currentState fields. The results will be limited to 10 cases and grouped by caseTypeId. Each grouping will also return a total of each grouping.

More information is available in API reference.

If you want to search by a specific case template, such Claims or Clients, or if you want to fetch more than the initial 10 records in a Global Search, then a case template-specific search is required.

query {
  caseTypeSearch(
    searchTerm: "time"
    caseTypeId: 57
    page: 2
    pageSize: 25
    sortField: "currentState"
    sortDirection: "asc"
  ) {
    total
    cases {
      id
      title
    }
  }
}

Above we're searching for the word "time" in any fields belonging to case template with id: 57. The query is retrieving cases appearing on page: 2 with a pageSize: 25. We're also specify that we want to sort the resultset by currentState in ascending order.

Once again we're only return id and title fields from each of the cases, and the total field to tell us how big the result set is.

More information is available in API reference.

Retrieving a bucket of cases

To retrieve a bucket of cases you need to know the ID of the bucket. You can find bucket ID by looking at the URL in the GUI, which will say something like .../buckets/156 where 156 is the ID. You can also find the ID by executing a query and iterating over the result set - see the next section on how to do so.

With the id: 156 in hand we can execute the following query to retrieve the contents of the bucket.

query {
  bucket(id: 156) {
    contents(page: 3, pageSize: 25) {
      statistics {
        kpis {
          key
          value
        }
        total
        totalCreated24hrs
        totalUpdated24hrs
      }
      cases {
        id
        title
      }
    }
  }
}

The results to the query above will contain two distinct sections, statistics and cases. The statistics section provides high-level counts on the contents of the bucket, including the Group By feature found in the GUI, identified here with kpis. The statistics section is mostly optional, other than total, which you'll need to paginate over the full bucket contents.

In this example we've chosen to retrieve id and title from the list of cases.

More information is available in API reference.

Find the ID of a Bucket

Finding the ID of a bucket belonging to a specific case template is achieved using the following query

query {
  currentUser {
    account {
      caseTypes(code: "claim") {
        buckets {
          id
          name
        }
      }
    }
  }
}

Specifying the code: "claim" filter is optional but it speeds up the query and reduces the load on the API.

Once you have the list buckets in the result set, all you need to do is iterate over the list, filtering by name, to get the id.

Executing a task against a case

Executing a case task only requires the caseTaskId. See the next section on how to get a caseTaskId.

mutation {
  executeCaseTask(caseTaskId: "t-4-23-8") {
    error 
    taskExecutionResult  {
      taskId
      result
      message
    }
  }
}

The example above executes the task and returns a new taskId, a result string and a message from the task.

Important note on task ids: If you want execute a task a second or third time, then you need to use the taskId returned from the initial call to executeCaseTask(...) as it may change from caseTaskId to taskId.

Find the task id in a case

Below is an example query of retrieving the task names and ids of tasks belonging to a case with id: 175.

query {
  case(caseId: 175) {
    tasklists {
      name
      tasks {
        name
        id
      }
    }
  }
}

More information is available in API reference.

Uploading a document to case

Uploading a document to an existing case is done using a traditional RESTFul HTTP interface. You still need to pass in an Authorization header, but instead calling a GraphQL endpoint you send a HTTP POST the following example URL:

https://acme.caseblocks.com/documents/32/73/28238

which follows the following pattern

https://{account-subdomain}.caseblocks.com/{accountId}/{caseTypeId}/{caseId}

  • accountId - is the id of the account which you can get by querying GraphQL with currentUser { account { id }}
  • caseTypeId - is the id of the case templatem
  • caseId - is the id of case you're uploading into.

You will also need to specify a newFileName form parameter which will be the name of the file as it will be found in the case's fileAttachments.

A curl-request looks as follows:

curl --location --request POST 'https://acme.caseblocks.com/documents/32/73/28238' \
      --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NSwiaWF0IjoxNTk5MjIxNjMzLCJleHAiOjE1OTkzMDgwMzN9.8L1ss49K6g3QHhKEmJxOgEc8KRUoXXXCvHOdezM8Tws' \
      --form 'file=@/C:/Users/jdoe/Downloads/file1.pdf'
      --form 'newFileName=file2.pdf'

In the example above file1.pdf is uploaded to case with id: 28238 and the file is renamed with newFileName=file2.pdf. The newFileName form field is entirely optional, and if omitted Caseblocks will use uploaded filename instead, e.g. file1.pdf.

Creating a new user

To create a user you need to specify an email address, password, and displayName. The displayName is used throughout the app in places like the Timeline, so attribute case events like updates to the user.

mutation {
  createUserWithPassword(email: "jdoe@acme.com", password: "noMoreSecrets", displayName: "Jane Doe") {
    error   
    user {
      id
    }
  }
}

The example above shows us returning an error flag and the newly created user's id.

More information is available in API reference.

Create a team

To create a you need to specify the team's displayName and whether members should have access to the Commsroom using the commsEnabled flag.

mutation {
  createTeam(displayName: "Customer Service", commsEnabled: true) {
    error
    team {
      id
    }
  }
}

The example above shows us returning an error flag and the newly created team's id.

More information is available in API reference.

Adding a user to a team

You need to know the team's id and the user's id to make a user a member of a team. You can get the ids from the createTeam(...) and createUserWithPassword(...) explained above or from the query in the next section.

mutation {
  createTeamMembership(teamId: 1, userId: 24) {
    error
  }
}

Retrieving a list of users and teams

The query below returns the list of teams and their members. The query also returns the list users and the teams they're each a member of.

query {
  currentUser {
    account {
      teams {
        id
        displayName
        users {
          id
        }
      }
      
      users {
        id
        email
        teams {
          id
        }
      }
    }
  }
}

Exporting a bucket

To export a bucket all you need is the bucket's id:

mutation {
  exportBucket(id: 156) {
    error
    job {
      id
    }
  }
}

The mutation will return a job id which is different to the bucket id.

Exporting a bucket is a background job and might take 10 seconds or several hours to export, depending on the volume of data held in the bucket.

You'll need to query the status of the job after the job is launched and the job id is returned. See the next section on monitoring job progress.

The error flag indicates whether the request to launch an export was successful rather than the export itself, e.g. the bucket id might be invalid.

Monitoring job progress

To monitor the progress of a job you need to specify the job's id:

query {
  job(id: 256) {
    error
    job {
      jobType
      jobStatus
      currentStep
      totalSteps
    }
  }
}

The query above returns a job for id: 256, containing the jobType which might be Export Bucket. The jobStatus will have values like Pending, Running, Completed. The currentStep and totalSteps values provide progress information, e.g. step 234 out a total of 1625 steps during a bucket export.

We suggest polling the API for job progress every 10 seconds or longer.

Rendering an email template

To render an email template you need the id of the template and a payload that fits the fields declared in the email template.

mutation {
  renderEmailTemplate(id: 78, payload: {
    firstName: "Jackie",
    claimReference: "HKB020202893",
    claimStatus: "Under Review",
    claimTotal: "USD 158.84"
  }) {
    error
    message
    rendering
  }
}

In the example above we're rendering email template with id: 78 and sending it the JSON payload containing firstName, claimReference, claimStatus, claimTotal. The fields in the payloads are arbitrary fields that are used by the template and are not directly linked to a case template's schema.

The mutation returns error and message fields to indicate success or failure as well as the render email template in rendering.

NOTE: renderEmailTemplate(...) can be used to render not just HTML emails, but also for example SMS texts.

Sending and email

To send an email and have it recorded as a Conversation inside of a Case execute the following mutation:

mutation {
  createConversation(
    caseId: 773
    subject: "Your order has shipped!"
    body: "Dear Jackie, ..."
    recipients: [{ email: "jdoe@gmail.com" }]
    attachmentIds: [34737, 9549]
  )
}

In the example above we're creating a new Conversation with caseId: 773, specifying subject and body of the email.

The list of recipients could be external addresses such as email: "jdoe@gmail.com" or internal user and team ids.

The attachmentIds list of ids refers to the list of fileAttachments on the Case object which will cause Caseblocks to send an email with those attachments included.

More information is available in API reference.