Skip to content

API

This page explains how to create use AireFrame's APIs to build custom integrations.

Authentication

All integration APIs require a bearer token provided by AireIdentity using the OAuth client credentials flow

To get a client credentials token you must have setup an AireIdentity client that can request the AireFrameApi scope.

Example Request:

POST https://identity.aireinnovate.com/connect/token
CONTENT-TYPE application/x-www-form-urlencoded
client_id=[MY_CLIENT]&
client_secret=[MY_CLIENT_SECRET]&
grant_type=client_credentials&
tenant_key=[MY_TENANT_ENVIRONMENT_KEY]&
scope=AireFrameApi

Subject API

Get Subjects

Query subjects by a variety of filters.

Required Permission

List:Subject

Endpoint: GET api/v2/subject

Query Parameters (All optional):

  • Filtering:

    • StructuralEntityKeys: String (Multiple can be provided, behaviour is OR)
    • Either:
      • SearchTerm: String
      • customFieldValueFilter.values[custom_field_key]: String (Multiple can be provided)
        • With optional customFieldValueFilter.match: ExactAll (Match all field values exactly) or ExactAny (Match any field value exactly) - Defaults to ExactAll
  • Paging:

    • After: String
    • Before: String
    • First: Integer (Defaults to 20 if First or Last is not provided)
    • Last: Integer
    • OrderBy: String
    • OrderDirection: Ascending or Descending

Example requests:

Get all subjects that are assigned to either key1 or key2 structural entities

/api/v2/subject?structuralEntityKey=key1&structuralEntityKey=key2

Fuzzy search subjects by the term 'Isaac'

/api/v2/subject?searchTerm=Isaac

Get all subjects with the custom field values 'given_names' = 'Isaac' and 'family_name' = 'Newton'

/api/v2/subject?customFieldValueFilter.values[given_names]=Isaac&customFieldValueFilter.values[family_name]=Newton&customFieldValueFilter.match=ExactAll

Example Response

Example response:

json
{
  "PageInfo": {
    "HasNextPage": false,
    "HasPreviousPage": false,
    "StartCursor": "c4e44f3d-f7c8-42f7-a9c7-c1e6d35c714b",
    "EndCursor": "c4e44f3d-f7c8-42f7-a9c7-c1e6d35c714b",
    "TotalCount": 1
  },
  "Edges": [
    {
      "Node": {
        "Id": "c4e44f3d-f7c8-42f7-a9c7-c1e6d35c714b",
        "ExternalId": "6c5827d9-ae1e-4581-826b-7884596f929c",
        "CustomFieldValues": [
          {
            "Field": {
              "Key": "given_names",
              "Name": "Given Names",
              "Type": "Text",
              "Required": true,
              "IsArray": false
            },
            "Value": {
              "DataType": "String",
              "ValueText": "Isaac"
            }
          },
          {
            "Field": {
              "Key": "family_name",
              "Name": "Family Name",
              "Type": "Text",
              "Required": true,
              "IsArray": false
            },
            "Value": {
              "DataType": "String",
              "ValueText": "Newton"
            }
          },
          {
            "Field": {
              "Key": "scientific_contributions",
              "Name": "Scientific Contributions",
              "Type": "Text",
              "Required": true,
              "IsArray": true
            },
            "Value": [
              {
                "DataType": "String",
                "ValueText": "Laws of Motion"
              },
              {
                "DataType": "String",
                "ValueText": "Universal Gravitation"
              }
            ]
          }
        ],
      },
      "Cursor": "c4e44f3d-f7c8-42f7-a9c7-c1e6d35c714b"
    }
  ]
}

Get Subject By Id

Returns details about a subject given their internal id.

Required Permission

View:Subject

Endpoint: GET api/v2/subject/{subjectId}

Where:

  • subjectId is AireFrame's internal identifier for the subject

Example response:

json
{
  "Id": "c4e44f3d-f7c8-42f7-a9c7-c1e6d35c714b",
  "ExternalId": "6c5827d9-ae1e-4581-826b-7884596f929c",
  "CustomFieldValues": [
    {
      "Field": {
        "Key": "given_names",
        "Name": "Given Names",
        "Type": "Text",
        "Required": true,
        "IsArray": false
      },
      "Value": {
        "DataType": "String",
        "ValueText": "Isaac"
      }
    },
    {
      "Field": {
        "Key": "family_name",
        "Name": "Family Name",
        "Type": "Text",
        "Required": true,
        "IsArray": false
      },
      "Value": {
        "DataType": "String",
        "ValueText": "Newton"
      }
    },
    {
      "Field": {
        "Key": "scientific_contributions",
        "Name": "Scientific Contributions",
        "Type": "Text",
        "Required": true,
        "IsArray": true
      },
      "Value": [
        {
          "DataType": "String",
          "ValueText": "Laws of Motion"
        },
        {
          "DataType": "String",
          "ValueText": "Universal Gravitation"
        }
      ]
    }
  ],
  "StructuralEntities": [
    {
      "Key": "e060a545-b6cc-4c80-bad9-440484538627",
      "DisplayName": "name",
      "ParentKey": null,
      "Depth": 1,
      "StructureType": {
        "Name": "name",
        "Key": "f36068c0-5b87-4b43-b3e0-6ee56d4865c2",
        "SubjectAssignable": true,
        "CustomFields": []
      },
      "CustomFieldValues": []
    }
  ]
}

Update Subject By Id

Updates a subject's custom field value(s).

Required Permission

Edit:Subject

Endpoint: PATCH api/v2/subject/{subjectId}

Body:

json
{
  "CustomFields": [
    {
      "Key": "string",
      "Value": {
        "<DataType>": {
          "Value": <Value>
        }
      }
    }
  ]
}

Where:

  • subjectId is AireFrame's internal identifier for the subject
  • CustomFieldValues is an array of key-values pairs for the custom fields from the structure type
    • Key references the assossiated custom field on the structure type
    • Value can be an array of objects (for multiple value custom fields) or an object containing:
      • Boolean (object): Contains a Value property for a boolean value.
      • String (object): Contains a Value property for string data.
      • Integer (object): Contains a Value property for an integer value.
      • Decimal (object): Contains a Value property for a decimal value.
      • DateTime (object): Contains a Value property for a date time value.
      • Date (object): Contains a Value property for a date value.
      • Time (object): Contains a Value property for a time value.
      • UserIdentifier (object): Contains a Value property for a user identifier.

Upsert (Create/Update) Subject

AireFrame can handle upsert subject messages provided that the subject upsert api has been configured - see here.

Required Permission

Create:Subject - If the subject does not exist

Edit:Subject - If the subject already exists

Create:SubjectLocation and Delete:SubjectLocation - If the subject exists and structural entity keys are provided

Endpoint: POST /api/v2/messaging/subject

Body:

json
{
  "CustomFieldValues": [
    {
      "Key": "single-value",
      "Value": {
        "<DataType>": {
          "Value": <Value>
        }
      }
    },
    {
      "Key": "array-value",
      "Value": [
        {
          "<DataType>": {
            "Value": <Value>
          }
        },
        {
          "<DataType>": {
            "Value": <Value>
          }
        }
      ]
    }
  ],
  "StructuralEntityKeys": ["key"]
}

Where:

  • CustomFieldValues is an array of key-value pairs for the custom fields from the subject configuration
    • Key references the assossiated custom field on the subject configuration
    • Value can be an array of objects (for multiple value custom fields) or an object containing:
      • Boolean (object): Contains a Value property for a boolean value.
      • String (object): Contains a Value property for string data.
      • Integer (object): Contains a Value property for an integer value.
      • Decimal (object): Contains a Value property for a decimal value.
      • DateTime (object): Contains a Value property for a date time value.
      • Date (object): Contains a Value property for a date value.
      • Time (object): Contains a Value property for a time value.
      • UserIdentifier (object): Contains a Value property for a user identifier.
  • StructuralEntityKeys is an optional list of structural entity keys, for behaviour see here.

TIP

The matching field(s) must always be present within the request body.

If a subject exists, all other fields are optional and the provided fields will be updated on the subject.

If the subject does not exist, all required fields must be provided.

The response will be the created subject:

{
    "internalId": "d6df60bb-0c6d-47ab-855b-23c98d58ee79",
    "externalId": "b38a64fe-df82-4510-92bb-314e26ff5509",
    "customFieldValues": [
        {
            "customField": {
                "id": "0eabc586-c18a-4ff5-8883-081e1615ea72"
            },
            "value": "value"
        }
    ]
}

Where internalId is AireFrame's subject identifier

Subject Location API

Add Subject To Location

Adds existing structural entities to a subject given structural entity keys.

Required Permission

Create:SubjectLocation

Endpoint: PUT api/v1/subject/{subjectId}/structuralEntities

Body:

{
    "keys" : [ "key1", "key2", "key3" ]
}

Where:

  • subjectId is AireFrame's internal identifier for the subject
  • keys is an array of structural entity keys

Remove Subject From Location

Removes structural entities from a subject.

Required Permission

Delete:SubjectLocation

Endpoint: DELETE api/v1/subject/{subjectId}/structuralEntities?keys={keys}

Where:

  • subjectId is AireFrame's internal identifier for the subject
  • keys is a comma separated list of structural entity keys. E.g. key1,key2,key3

Subject Portal API

Get Subject Portal Users

Returns the users who have access to the subject via the subject access portal, given that subject access has been enabled.

Required Permission

View:SubjectAccessInvite

Endpoint: GET api/v1/subject/{subjectId}/subjectAccessUsers

Where:

  • subjectId is AireFrame's internal identifier for the subject

Optional paging query params:

  • Paging:
    • After: String
    • Before: String
    • First: Integer
    • Last: Integer
    • OrderBy: String
    • OrderDirection: Ascending or Descending

Example response

json
{
    "edges": [
        {
            "cursor": "MDpBcHByb3ZlZCBVc2VyOjdiMTc3ZDEyLWE2N2MtNDJhMS04NmFhLTNjMTBiZTgxZDMxNw==",
            "node": {
                "displayName": "User 1",
                "email": "user1@example.com",
                "id": "7b177d12-a67c-42a1-86aa-3c10be81d317",
                "inviteMethod": "SelfAccess"
            }
        },
        {
            "cursor": "MDpJbnZpdGVkIFN1YmplY3RTZWxmQWNjZXNzVXNlcjo0MDdkZWMzMC1lODg3LTQ4MWMtOTdhYS0wODMwMDdmM2NkMWI=",
            "node": {
                "displayName": "User 2",
                "email": "user2@example.com",
                "id": "407dec30-e887-481c-97aa-083007f3cd1b",
                "inviteMethod": "ThirdParty"
            }
        },
    ],
    "pageInfo": {
        "endCursor": "MTpcbnVsbDo3Yjc1Y2JhZi00YTI3LTQ2ZWMtOWJmNS1jZDk1ZTViNDQ5MTA=",
        "hasNextPage": false,
        "hasPreviousPage": false,
        "startCursor": "MDpBcHByb3ZlZCBVc2VyOjdiMTc3ZDEyLWE2N2MtNDJhMS04NmFhLTNjMTBiZTgxZDMxNw==",
        "totalCount": 2
    }
}

Response codes:

  • 403 indicates that the client does not have the required permission.
  • 404 indicates the subject could not be found.

Invite Subject To Portal

Invites a subject to use the subject portal, given that it has been enabled - see here.

Required Permission

Create:SubjectAccessInvite

Endpoint: POST api/v1/subject/{subjectId}/invite

Body:

json
["user@example.com"]

Where:

  • subjectId is AireFrame's internal identifier for the subject
  • The body is an optional array of emails for third party users to invite.
    • If this is provided, third-party access must be enabled.
    • If this is not provided, self-access must be enabled.

Example responses:

  • 200 indicates a successful invitation.
  • 403 indicates that the client does not have the required permission.
  • 404 indicates the subject could not be found.
  • 409 indicates the subject portal is not configured or the subject does not have values for the matching field(s) required for the invitation.

Remove Access to Portal

Removes a subjects or third party users access to the subject portal.

Required Permission

Delete:SubjectAccessInvite

Endpoint: DELETE api/v1/subject/{subjectId}/invite

Where:

  • subjectId is AireFrame's internal identifier for the subject

Supported Query Params:

  • thirdPartyUserEmails - an optional array of emails for third party users to remove access to the subject portal.
    • If this is provided, third-party access must be enabled.
    • If this is not provided, self-access must be enabled.

Example responses:

  • 200 indicates a successful invitation.
  • 403 indicates that the client does not have the required permission.
  • 404 indicates the subject could not be found.
  • 409 indicates the subject portal is not configured or the subject does not have values for the matching field(s) required for the invitation.

User API

Get Users

By default returns all active users. Results can be modified using the query parameters.

Endpoint: GET api/v1/users

Required Permission

List:User

Supported Query Params:

  • searchTerm - For searching users by name
  • includeInactive - For including inactive users
  • withAccessToSubjectId - For filtering down to users who have access to the subject via groups and the associated structural entities. Note: this is the AireFrame subjectId

Example response:


[{
    id: "user-identifier",
    displayName: "Test User"
}]

Structural Entity API

Get Structural Entities

Required Permission

List:StructuralEntity

Endpoint: GET api/v1/structuralEntity

Query Parameters (All optional):

  • Filtering:

    • ParentKey: String
    • Depth: Integer
    • SearchTerm: String
    • SubjectAssignable: Boolean
    • StructureTypeKey: String
  • Paging:

    • After: String
    • Before: String
    • First: Integer (Defaults to 20 if First or Last is not provided)
    • Last: Integer
    • OrderBy: String
    • OrderDirection: Ascending or Descending

Example response:

{
  "PageInfo": {
    "HasNextPage": false,
    "HasPreviousPage": false,
    "StartCursor": "e060a545-b6cc-4c80-bad9-440484538627",
    "EndCursor": "f8a2dd4c-aa4e-4215-a830-316543fed34a",
    "TotalCount": 1
  },
  "Edges": [
    {
      "Node": {
        "Key": "e060a545-b6cc-4c80-bad9-440484538627",
        "DisplayName": "name",
        "ParentKey": null,
        "Depth": 1,
        "StructureType": {
          "Name": "name",
          "Key": "f36068c0-5b87-4b43-b3e0-6ee56d4865c2",
          "SubjectAssignable": true,
          "CustomFields": []
        },
        "CustomFieldValues": []
      },
      "Cursor": "e060a545-b6cc-4c80-bad9-440484538627"
    }
  ]
}

Get StructuralEntity By Key

Returns details about a structural entity that matches a given key.

Required Permission

View:StructuralEntity

Endpoint: GET api/v1/structuralEntity/{structuralEntityKey}

Where:

  • structuralEntityKey is the unique key for the structural entity

Example response:


{
  "Key": "e060a545-b6cc-4c80-bad9-440484538627",
  "DisplayName": "name",
  "ParentKey": null,
  "Depth": 1,
  "StructureType": {
    "Name": "name",
    "Key": "f36068c0-5b87-4b43-b3e0-6ee56d4865c2",
    "SubjectAssignable": true,
    "CustomFields": []
  },
  "CustomFieldValues": []
}

Upsert (Create/Update) Structural Entity

Required Permission

Create:StructuralEntity - If the structural entity does not exist

Edit:StructuralEntity - If the structural entity already exists

Endpoint: PUT api/v1/structuralEntity

Body:

{
    "Key": string,
    "DisplayName": string,
    "ParentKey": string (optional),
    "StructureTypeKey": string,
    "CustomFieldValues": [
        {
            "Key": string,
            "Value": {
                "<DataType>": {
                    "Value": <Value>
                }
            }
        }
    ]
}

Where:

  • Key is the key for the existing structural entity
  • DisplayName is the new display name for the existing structural entity
  • ParentKey is the key of the new parent to this structural entity
  • StructureTypeKey is the key of the related structure type
  • CustomFieldValues is an array of key-values pairs for the custom fields from the structure type
    • Key references the assossiated custom field on the structure type
    • Value is an object containing:
      • Boolean (object): Contains a Value property for a boolean value.
      • String (object): Contains a Value property for string data.
      • Integer (object): Contains a Value property for an integer value.
      • Decimal (object): Contains a Value property for a decimal value.
      • DateTime (object): Contains a Value property for a date time value.
      • Date (object): Contains a Value property for a date value.
      • Time (object): Contains a Value property for a time value.
      • UserIdentifier (object): Contains a Value property for a user identifier.

Example Request

{
    "Key": "name",
    "DisplayName": "Name",
    "ParentKey": "parent-key",
    "StructureTypeKey": "structure-type-key",
    "CustomFieldValues": [
        {
            "Key": "city",
            "Value": {
                "String": {
                    "Value": "London"
                }
            }
        }
    ]
}

The Response will be the updated Structural Entity:

{
  "Key": "9718d040-5f2d-4a56-9771-9140a06e460e",
  "DisplayName": "New Name",
  "ParentKey": null,
  "Depth": 1,
  "StructureType": {
    "Name": "name",
    "Key": "188913dc-95cf-408b-ae52-cea05aee921c",
    "SubjectAssignable": true,
    "CustomFields": [
      {
        "Name": "City",
        "Key": "city",
        "Type": "text",
        "Required": false
      }
    ]
  },
  "CustomFieldValues": [
    {
      "Field": {
        "Name": "City",
        "Key": "city",
        "Type": "text",
        "Required": false
      },
      "Value": {
        "$type": "string",
        "DataType": "String",
        "Value": "London",
        "ValueText": "London"
      }
    }
  ]
}

Data Set API

Refresh Data Set

Endpoint: POST api/v1/dataSet/{dataExtractKey}/refresh

Where:

  • dataExtractKey is the key of the data extract you want to refresh the data set for

Returns:

  • 200 OK - If the data set was successfully refreshed
  • 404 Not Found - If the data extract key does not exist