Compusense Standard APIs

Compusense Standard APIs

Overview

The Compusense Standard APIs let your own systems exchange data with your Compusense subscription automatically. You can pull completed test data into a data warehouse or dashboard, keep your Product library in sync with your internal product catalogue, add samples to your sample list from another system, and check on tests that are currently running.

This article explains what each API does, how to connect, and the key behaviours your developers should plan for. It is written for the analysts and IT or data teams who set up and maintain these integrations.

You can review the calls for the APIs on our sandbox setup here: Compusense Standard APIs sandbox.

Available APIs

APIWhat it doesCommon use
Test-Data APIsRetrieves test definitions, panelist responses, presentation designs, and panelist participation for your tests.A nightly export of completed results into a data warehouse, BI tool, or statistics package.
Product APIsLooks up, creates, and updates products in your Product library, and lists your custom product fields and product groups.Keeping Compusense in sync with your product master data.
Sample List APIAdds samples to the sample list for an analyst group.Sending samples from a LIMS or other system of record.
Running Test Detail APIsLists tests that are currently running and shows panelist progress through each sample set.Live monitoring dashboards during panel sessions.

ℹ Info: One set of credentials works for all of the Standard APIs. If you already use one Standard API, you do not need separate access to use the others.

Before You Begin

Compusense provides three values for your subscription. You need all three to connect.

  • A client ID.
  • A client secret.
  • Your API address.

⚠ Warning: Store your client ID and client secret in a secure location, such as a secrets manager. Do not save them in source code or share them by email.

Connecting to the APIs

The Standard APIs use the OAuth 2.0 Client Credentials flow. Your system first requests an access token, then sends that token with every API call.

Request an Access Token

  1. Send a POST request to the Compusense token endpoint.
  2. Include the following headers.
    HeaderValue
    Acceptapplication/json
    AuthorizationBasic, followed by your client ID and client secret joined with a colon and Base64 encoded
    Cache-Controlno-cache
    Content-Typeapplication/x-www-form-urlencoded
  3. Include these two values in the request body, exactly as shown.
    grant_type=client_credentials scope=custom.api.read
  4. Take the access_token value from the response and send it in the Authorization header of every API call, in the format Bearer followed by the token.

Most HTTP libraries can build the Basic authorization value for you. For a short explanation of the encoding step, see Okta's guide, Request for token.

ℹ Info: Each access token is valid for 1 hour. Request a new token before the hour is up, especially for long-running jobs.

Test-Data APIs

The Test-Data APIs are five calls that work together. The first call finds the tests you want, and the other four retrieve the data for one test at a time.

EndpointWhat it returns
GET Tests/FindA list of test IDs within a time window, optionally filtered by analyst group.
GET Tests/{testid}The test definition, including status, sections, samples, linked products, and questions.
GET Tests/{testid}/resultsEvery panelist response for the test.
GET Tests/{testid}/designdetailsThe order in which each panelist saw sections, samples, attributes, and choices.
GET Tests/{testid}/panelistsThe panelists assigned to the test, their completion status, and the stars, strikes, and points awarded on the test.

Most clients run a nightly job that collects every test completed since the previous run.

  1. Call Tests/Find with dateType=3, using the time of your last successful run as start and the current time as end. Both start and end are required and use Unix time in seconds, UTC.
    GET /api/v1/Tests/Find?start=1779374786&end=1779461186&dateType=3
  2. To limit results to specific analyst groups, add analystGroupIds once for each group, for example analystGroupIds=5&analystGroupIds=12.
  3. Take the first test ID from the list and call Tests/{testid}.
  4. Call the results, designdetails, and panelists endpoints for the same test ID.
  5. Save the test in your system using the test ID as the key, replacing any earlier copy of the same test.
  6. Repeat steps 3 to 5 for each remaining test ID, one test at a time.
  7. Record the time of this run so it can be used as the start of the next run.

Choosing a Date Type

The dateType value tells Tests/Find which date to compare against your time window. If you leave it out, the API uses 0. The start time must be earlier than the end time, and each analyst group ID can be listed only once, otherwise the request returns a 400 error. If you leave out analystGroupIds, the API returns tests from every analyst group your credentials can access.

ValueReturns tests that were...
0, Last modifiedCreated, edited, or received results during the window, including tests still in progress.
1, StartScheduled to start during the window.
2, EndScheduled to end during the window.
3, Completed (recommended)Set to Complete during the window. Every test returned has finalised results.
4, CreatedCreated during the window.

What to Expect in Your Test Data

  • The same test can appear in more than one run. If an analyst re-opens a completed test and completes it again, it is returned again with the same test ID. Save tests by test ID and overwrite the earlier copy rather than treating it as an error.
  • Deleted tests are not returned by Tests/Find. If you already hold a test in your system, you can call Tests/{testid} to check on it. A test in the recycle bin is returned with isDeleted set to true.
  • Tests in Draft status have no results. Calling the results endpoint for a Draft test returns an error, so check the test status first.
  • A panelist is marked Complete when they reach the thank-you screen. Depending on the test design, branching, or conditional questions, a Complete panelist may not have answered every question for every sample, so check each response rather than assuming every question was answered.
  • No personal information is returned. Panelists are identified by an ID that stays the same across every test they take. For anonymous tests, no panelist list is returned and every panelist ID is 0, so group responses by sample set number instead.
  • Stars, strikes, and points show what was awarded on that test only, not a panelist's lifetime totals. A panelist who completed a test can still have strikes if the test was re-opened so they could finish.
  • Responses to Photo Upload questions are not available through the API. These questions appear with a question type of unknown.
  • Dates and times are Unix time in seconds, UTC.
  • Each call returns its full result in a single response, with no paging. Large tests with hundreds of panelists can return several megabytes of data.

Product APIs

The Product APIs give your system read and write access to your Product library.

EndpointWhat it does
GET Products/Find?productCode=Returns one product by its product code. The match is not case sensitive.
GET Products/HeadersLists your custom product fields, the type of each field, and the allowed options for choice fields.
GET Products/ProductGroupsLists your product groups.
POST Products/UpsertCreates a product, or updates it if the product code already exists.

Things to Know

  • Custom fields and product groups are matched by name. Call Headers and ProductGroups first so you send the exact names configured in your subscription.
  • Custom field values are always sent and returned as text. Use the field type from Headers to format them.
    • Checkbox: true or false.
    • Number: a whole number.
    • Date: YYYY-MM-DD.
    • Choice: one of the listed options. These are not case sensitive.
  • If a request includes a custom field name that does not exist, or a value that does not fit the field type, the whole request is rejected with a 400 error.
  • Product group names that do not match a group in your subscription are ignored without an error. A new product must include at least one valid product group, or the request returns a 404 error. Product groups are only ever added by Upsert, never removed.
  • On an update, the product name is always replaced. Custom fields you leave out keep their current values. If you leave out Active, the product's active status does not change.
  • Products cannot be deleted through the API. To archive a product, send Active as false, and to restore it, send Active as true. Archived products cannot be linked to new samples.
  • The Upsert response does not say whether the product was created or updated. Call Find first if you need to know.
  • If you send both a product ID and a product code and they belong to different products, the request is rejected with a 409 error.
  • Upsert requires Product Library Admin permission. Without it, the request returns a 403 error.

Sample List API

The Sample List API adds one sample per call to the sample list of an analyst group. Place the analyst group ID in the address, not in the request body.

POST /api/v1/SampleLibrary/Insert/{analystGroupId}
FieldRequiredNotes
SampleNameYesThe name of the sample. This is the only required field.
ProductCodeNoLinks the sample to a product with this code. If no matching product exists, the sample is still created without a product link, the code is discarded, and no error is returned.
CustomDataNoA list of key and value pairs. Each key must match one of your custom field names. The match is not case sensitive. If any key does not match, the whole request fails with a 500 error and no sample is created. Values must use these formats.
  • Date: MM/DD/YYYY.
  • Checkbox: 1 or 0.
  • Number: a whole number.
  • Choice: one of the listed options, matched exactly, including capital letters.
IsEditableNoControls whether analysts can edit the sample in Compusense once it is used in a test. The default is false, so samples are not editable unless you send true. Leave it as false when your own system is the source of truth for samples.

The response includes the SampleId of the new sample and its ProductSectionId.

✎ Note: An unmatched product code does not return an error, and an unmatched custom field name fails the whole request with a general server error. We recommend checking your field names with Products/Headers and confirming the product exists and is active with Products/Find before you send samples.

Running Test Detail APIs

These two endpoints support live monitoring of tests that are in progress. To retrieve finished test data, use the Test-Data APIs instead.

  • GET Tests/GetRunningTests returns every test currently running in your subscription, with its test ID, name, type, scheduled start and stop times, folder, panelist count, and tags. If no tests are running, the list is empty.
  • GET Tests/GetSampleSetInformation/{testId} returns the sample sets for one running test, including the panelist ID, each sample's blinding code, and the time each sample set was completed.

Best Practices for Reliable Integrations

⚠ Warning: Process requests one at a time. Sending large numbers of requests at the same time can slow down your live Compusense subscription for your analysts and panelists.

  • Finish all calls for one test before starting the next.
  • When loading historical data, split the time window into smaller periods, such as one week at a time, rather than requesting years of data in a single call.
  • Pause briefly between calls when processing large batches.
  • Request a new access token before the current one expires.
  • If one item fails, log it and continue with the next item so a single problem does not stop the whole run.

Response Codes

Error messages vary between APIs, so base your error handling on the status code rather than the message text.

CodeWhat it meansWhat to do
200The request was successful.No action needed.
400The request is not valid, for example a required value is missing, a custom field value does not fit its field type, or the token request has the wrong scope or grant type.Correct the request. Do not retry it unchanged.
401The access token is missing, has expired, or does not have the required scope, or your credentials have not been set up for API access.Request a new token and retry once. If the error continues, contact Compusense Support.
403The token is valid but does not have access to what was requested, for example an analyst group outside your permissions.Remove the item you do not have access to. Do not retry.
404The item does not exist or the address is incorrect. For Product Upsert, this can also mean a new product has no valid product group.Check the address, the ID, and the request body. Do not retry.
405The wrong request method was used, for example GET on Products/Upsert.Use POST for Upsert and Insert calls.
409The product ID and product code in an Upsert belong to different products.Send matching values, or send only one of them.
500A server error. For the results endpoint, every error is returned as 500, including a test in Draft status, a test that does not exist, or a test you cannot access. A sample insert with an unmatched custom field name also returns 500.Check the test status and your request first. For other server errors, including 502, 503, and 504, retry up to three times with increasing waits, such as 2, 8, and 30 seconds.

Getting Help

To request access to the Standard APIs, or if you need help with an integration, contact Compusense Support. Include the endpoint you called, the time of the request, the status code you received, and any test IDs involved. Never include your client secret or access token in a support request.