NAV
shell graphql javascript

Introduction

Welcome to the Glific API! You can use this API to access the Glific endpoint via GraphQL. This is the interface used between the Glific FrontEnd and BackEnd and as such is expected to be complete, documented and tested.

We have language bindings in GraphQL and shell (for authentication). You can view code examples in the dark area to the right.

API Endpoint

For NGOs who already have an account with Glific, your API endpoint is "api." concatenated with your current url. Thus if your Glific URL is: https://ilp.tides.coloredcow.com/, your API endpoint will be: https://api.ilp.tides.coloredcow.com/api

Note that for authentication we use REST, and for the rest of the API we use GraphQL. We have also implemented GraphQL subscriptions if you want to be informed when we receive a message and other events.

Webhooks

Webhooks in Glific are called from floweditor as part of a flow. You need to choose, "Call a webhook" as the action of a node. We recommend that you implement the POST method for your webhook. This is because we currently send a standard body as part of the webhook which includes potentially sensitive contact related information.

Also give a meaninful name to the 'result'. So for a webhook that computes the survey score based on the user responses in the flow, the name can be 'survey'.

Prerequisites

You need to host and maintain a public URL that is the destination of your webhook.

Webhook parameters

Glific sends a standard json object with contact and results fields as default fields in the POST body. In addition to that Glific supports sending additional data in form of JSON fields.

{
  "contact": {
    "name": "Name of Contact",
    "phone": "Phone of Contact",
    "fields": {
      "field 1 key": {
        "type": "type of field",
        "label": "label of field",
        "value": "value of field",
        "inserted_at": "inserted time of field"
      },
      ...
      "field n key": {
          "type": "type of field",
          "label": "label of field",
          "value": "value of field",
          "inserted_at": "inserted time of field"
      }
    }
  },
  "results": {
    "result 1 key": {
      "input": "input of result",
      "category": "category of result"
    },
    ...
    "result n key": {
      "input": "input of result",
      "category": "category of result"
    },
  },
  "custom_key": "custom_value"
}

Note: When you make a get request all this data will go as json string in a parameter called data

Webhook Authentication

By default, Glific adds an extra signature header to each webhook to indicate that this was sent from Glific. This signature key is generated using the signature phrase you set up for your organization and is also encrypted with the current time, which is part of the signature payload. More details on how we sign the payload and how to verify its accuracy can be found in How we verify webhooks

Webhook Return Values

On successful completion of the webhook, return a status code of 200 along with a JSON body. The JSON body, should only be composed of {key, value} pairs. Each of these key value pairs is then stored in the flow "results" map, with the key being appended to the variable indicated in the "Call a Webhook" node.

Thus if your 'survey' webhook, returns three values: 'score', 'message', 'content', Glific will add:

{
  "results": {
    ... (results in flow currently)
    "survey.score": "Score you set in webhook",
    "survey.message": "Message you want to send next to the user",
    "survey.content": "Content you want to send next to the user"
  }
}

The format of the return value is here

{
    "return 1 key": "return 1 value",
    "return 2 key": "return 2 value",
    ...
    "return n key": "return n value"
}

An example implementation of a webhook can be seen in our github repository

Authentication

We do not use GraphQL for authorization, but use REST to generate and renew tokens. The authentication tokens should be included in all GraphQL requests. This section will be expanded to also include roles and permissions. User management will be done via GraphQL

The main API endpoints are listed below

Send an OTP request to verify a phone number

The OTP will be sent via WhatsApp and the NGO's Glific Instance. The API will only send a message to contacts that have opted into the system. This also prevents the API from being abused.

curl -X POST -d \
  "user[phone]=911234554321" \
  http://YOUR_HOSTNAME_AND_PORT/api/v1/registration/send-otp
If you are using axios or other libraries, send the following in the BODY of a POST request

{
    "user": {
        "phone": "911234554321"
    }
}

The above query returns JSON structured like this:

{"data": {"phone": phone,
          "message": "OTP sent successfully to #{phone}"}}

Or

{"error": { "message": "Cannot send the otp to #{phone}"}}

Send an OTP request to verify a phone number of existing user

The OTP will be sent via WhatsApp and the NGO's Glific Instance. The API will only send a message to existing user

curl -X POST -d \
  "user[phone]=911234554321&user[registration]=false" \
  http://YOUR_HOSTNAME_AND_PORT/api/v1/registration/send-otp
If you are using axios or other libraries, send the following in the BODY of a POST request

{
    "user": {
        "phone": "911234554321",
        "registration": "false"
    }
}

The above query returns JSON structured like this:

{"data": {"phone": phone,
          "message": "OTP sent successfully to #{phone}"}}

Or

{"error": { "message": "Cannot send the otp to #{phone}"}}

Create a new user

The typical user registration flow will be something like:

curl -X POST -d \
  "user[name]='Test User'&user[phone]=911234554321&user[password]=secret1234 \
  &user[otp]=321721" \
  http://YOUR_HOSTNAME_AND_PORT/api/v1/registration
If you are using axios or other libraries, send the following in the BODY of a POST request

{
    "user": {
        "name": "Test User",
        "phone": "911234554321",
        "password": "secret1234",
        "otp": "321721"
    }
}

The above query returns JSON structured like this:

{
    "data": {
        "access_token": "AUTH_TOKEN",
        "token_expiry_time": "2020-07-13T16:22:53.678465Z",
        "renewal_token": "RENEW_TOKEN"
    }
}

Glific expects for the auth token to be included in all API requests to the server in a header that looks like the following:

Authorization: AUTH_TOKEN

Create a new session for an existing user

curl -X POST -d \
  "user[phone]=911234554321&user[password]=secret1234" \
  http://YOUR_HOSTNAME_AND_PORT/api/v1/session
If you are using axios or other libraries, send the following in the BODY of a POST request

{
    "user": {
        "phone": "911234554321",
        "password": "secret1234"
    }
}

The above query returns JSON structured like this:

{"data":
  {
    "data": {
          "access_token": "AUTH_TOKEN",
          "token_expiry_time": "2020-07-13T16:22:53.678465Z",
          "renewal_token": "RENEW_TOKEN"
      }
  }
}

Renew an existing session

curl -X POST -H "Authorization: RENEW_TOKEN" \
  http://localhost:4000/api/v1/session/renew

The above query returns JSON structured like this:

{"data":
  {
    "data": {
          "access_token": "AUTH_TOKEN",
          "token_expiry_time": "2020-07-13T16:22:53.678465Z",
          "renewal_token": "RENEW_TOKEN"
      }
  }
}

Delete an existing session

curl -X DELETE -H "Authorization: AUTH_TOKEN" \
  http://localhost:4000/api/v1/session

The above query returns JSON structured like this:

{"data":{}}

reset password

The typical forgot password flow will be something like:

curl -X POST -d \
  "user[phone]=911234554321&user[new_password]=secret1234 \
  &user[otp]=321721" \
  http://YOUR_HOSTNAME_AND_PORT/api/v1/registration/reset-password
If you are using axios or other libraries, send the following in the BODY of a POST request

{
    "user": {
        "phone": "911234554321",
        "password": "secret1234",
        "otp": "321721"
    }
}

The above query returns JSON structured like this:

{
    "data": {
        "access_token": "AUTH_TOKEN",
        "token_expiry_time": "2020-07-13T16:22:53.678465Z",
        "renewal_token": "RENEW_TOKEN"
    }
}

Languages

Get All Languages

query languages($opts: Opts) {
  languages(opts: $opts){
    id
    label
    labelLocale
    locale
    isActive
    localized
  }
}

{
  "opts": {
    "order": "DESC",
    "limit": 10,
    "offset": 0
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "languages": [
      {
        "id": "1",
        "isActive": false,
        "label": "Hindi",
        "labelLocale": "हिंदी",
        "locale": "hi",
        "localized": true
      },
      {
        "id": "2",
        "isActive": false,
        "label": "English",
        "labelLocale": "English",
        "locale": "en",
        "localized": true
      }
    ]
  }
}

This returns all the languages filtered by the input LanguageFilter

Query Parameters

Parameter Type Default Description
filter LanguageFilter nil filter the list
opts Opts nil limit / offset / sort order options

Return Parameters

Type Description
[Language] List of languages

Get a specific language by ID

query language($id: ID!) {
  language(id: $id) {
    language {
      id
      label
    }
  }
}

{
  "id": 2
}

The above query returns JSON structured like this:

{
  "data": {
    "language": {
      "language": {
        "id": "2",
        "label": "English"
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required

Return Parameters

Type Description
LanguageResult Queried Language

Count all Languages

query countLanguages {
  countLanguages
}

The above query returns JSON structured like this:

{
  "data": {
    "countLanguages": 2
  }
}

Query Parameters

Parameter Type Default Description
filter LanguageFilter nil filter the list

Return Parameters

Type Description
Int Count of languages

Create a Lanuguage

mutation createLanguage($input:LanguageInput!) {
  createLanguage(input: $input) {
    language {
      id
      label
      labelLocale
      locale
      isActive
    }
    errors {
      key
      message
    }
  }
}

{
  "input": {
    "label": "Kannada",
    "isActive": true,
    "locale": "kn",
    "labelLocale": "Kannada"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "createLanguage": {
      "errors": null,
      "language": {
        "id": "3",
        "isActive": true,
        "label": "Kannada",
        "labelLocale": "Kannada",
        "locale": "kn"
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
input LanguageInput required

Return Parameters

Type Description
LanguageResult The created language object

Update a Language

mutation updateLanguage($id: ID!, $input: LanguageInput!) {
  updateLanguage(id: $id, input: $input) {
    language {
      id
      label
      labelLocale
      locale
      isActive
    }
    errors {
      key
      message
    }
  }
}

{
  "id": 3,
  "input": {
    "label": "Kannada",
    "isActive": false,
    "locale": "kn",
    "labelLocale": "Kannada"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "updateLanguage": {
      "errors": null,
      "language": {
        "id": "3",
        "isActive": false,
        "label": "Kannada",
        "labelLocale": "Kannada",
        "locale": "kn"
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required
input LanguageInput required

Return Parameters

Type Description
LanguageResult The updated language object

Delete a Language

mutation deleteLanguage($id: ID!) {
  deleteLanguage(id: $id) {
    errors {
      key
      message
    }
  }
}

{
  "id": "3"
}

The above query returns JSON structured like this:

{
  "data": {
    "deleteLanguage": {
      "errors": null
    }
  }
}

In case of errors, all the above functions return an error object like the below

{
  "data": {
    "deleteLanguage": {
      "errors": [
        {
          "key": "Elixir.Glific.Settings.Language 3",
          "message": "Resource not found"
        }
      ]
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required

Return Parameters

Type Description
LanguageResult An error object or empty

Language Objects

Language

Field Argument Type Description
id ID
isActive Boolean
label String
labelLocale String
locale String

LanguageResult

Field Argument Type Description
errors [InputError]
language Language

Language Inputs

LanguageFilter

Filtering options for languages

Field Type Description
label String Match the label
locale String Match the locale
localized Boolean Match the localized

LanguageInput

Field Type Description
isActive Boolean
localized Boolean
isReserved Boolean
label String! Unique
labelLocale String!
locale String!

Providers

Get All Providers

query providers($filter: ProviderFilter, $opts: Opts) {
  providers(filter: $filter, opts: $opts) {
    id
    name
    shortcode
    keys
    secrets
    group
    description
    isRequired
  }
}

{
  "opts": {
    "limit": 10,
    "offset": 1,
    "order": "ASC"
  },
  "filter": {
    "name": "Default"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "providers": [
      {
        "id": "3",
        "keys": "{}",
        "name": "Dialogflow",
        "secrets": "{}",
        "shortcode": "dialogflow",
        "group": null,
        "description": "Provider for Dialogflow"
      },
      {
        "id": "2",
        "keys": "{}",
        "name": "Gupshup",
        "secrets": "{}",
        "shortcode": "gupshup",
        "group": "bsp",
        "description": "BSP provider"
      }
    ]

This returns all the providers filtered by the input ProviderFilter

Query Parameters

Parameter Type Default Description
filter ProviderFilter nil filter the list
opts Opts nil limit / offset / sort order options

Return Parameters

Type Description
[Provider] List of providers

Get a specific Provider by ID

query provider($id: ID!) {
  provider(id: $id) {
    provider {
      id
      name
      shortcode
      keys
      secrets
      group
      isRequired
    }
  }
}

{
  "id": 1
}

The above query returns JSON structured like this:

{
  "data": {
    "provider": {
      "provider": {
        "group": "bsp",
        "id": "1",
        "isRequired": true,
        "keys": "{}",
        "name": "Gupshup",
        "secrets": "{}",
        "shortcode": "gupshup"
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
filter ProviderFilter nil filter the list

Return Parameters

Type Description
ProviderResult Queried Provider

Count all Providers

query countProviders($filter: ProviderFilter) {
  countProviders(filter: $filter)
}

{
  "filter": {
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "countProviders": 3
  }
}

Query Parameters

Parameter Type Default Description
filter ProviderFilter nil filter the list

Return Parameters

Type Description
Int Count of filtered providers

Get BSP balance for an organization

query provider_queries {
  bspbalance
}

The above query returns JSON structured like this:

{
  "data": {
    "bspbalance": "{\"balance\":0.426}"
  }
}

Return Parameters

Type Description
JSON with "balance" as name and the amount of remaining balance as value

Create a Provider

mutation createProvider($input:ProviderInput!) {
  createProvider(input: $input) {
    provider {
      id
      name
    }
    errors {
      key
      message
    }
  }
}

{
  "input": {
    "name": "new_provider",
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "createProvider": {
      "errors": null,
      "provider": {
        "id": "4",
        "name": "new_provider",
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
input ProviderInput required

Return Parameters

Type Description
ProviderResult The created provider object

Update a Provider

mutation updateProvider($id: ID!, $input:ProviderInput!) {
  updateProvider(id: $id, input: $input) {
    provider {
      id
      name
    }
    errors {
      key
      message
    }
  }
}

{
  "id": "1",
  "input": {
    "name": "Updated Provider",
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "updateProvider": {
      "errors": null,
      "provider": {
        "id": "1",
        "name": "Updated Provider",
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required
input ProviderInput required

Return Parameters

Type Description
ProviderResult The updated provider object

Delete a Provider

mutation deleteProvider($id: ID!) {
  deleteProvider(id: $id) {
    provider {
      id
      name
    }
    errors {
      key
      message
    }
  }
}

{
  "id": "3"
}

The above query returns JSON structured like this:

{
  "data": {
    "deleteProvider": {
      "errors": null,
      "provider": null
    }
  }
}

In case of errors, all the above functions return an error object like the below

{
  "data": {
    "deleteProvider": {
      "errors": [
        {
          "key": "Elixir.Glific.Partners.Provider 3",
          "message": "Resource not found"
        }
      ]
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required

Return Parameters

Type Description
ProviderResult An error object or empty

Provider Objects

Provider

Field Argument Type Description
shortcode String
id ID
name String
group String
description String
isRequired Boolean
keys Json structure for keys
secrets Json structure for secrets
insertedAt DateTime
updatedAt DateTime

Bsp Balance

Field Argument Type Description
bspbalance Json

ProviderResult

Field Argument Type Description
errors [InputError]
provider Provider

Provider Inputs

ProviderFilter

Filtering options for providers

Field Type Description
name String Match the name
shortcode String Match the shortcode of provider

ProviderInput

Field Type Description
shortcode String
name String
group String
description String
isRequired Boolean
keys Json structure for keys
secrets Json structure for secrets

Organizations

Get All Organizations

query organizations($filter: OrganizationFilter, $opts: Opts) {
  organizations(filter: $filter, opts: $opts) {
    id
    name
    defaultLanguage {
      id
      label
    }
    activeLanguages {
      id
      label
    }
    isActive
    timezone
  }
}

{
  "opts": {
    "limit": 10,
    "offset": 1,
    "order": "ASC"
  },
  "filter": {
    "defaultLanguage": "Hindi"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "organizations": [
      {
        "activeLanguages": [
          {
            "id": "1",
            "label": "Hindi"
          },
          {
            "id": "2",
            "label": "English"
          }
        ],
        "defaultLanguage": {
          "id": "1",
          "label": "Hindi"
        },
        "id": "1",
        "name": "Default Organization",
        "isActive": true,
        "timezone": "Asia/Kolkata"
      },
      {
        "defaultLanguage": {
          "id": "1",
          "label": "Hindi"
        },
        "id": "2",
        "name": "Slam Out Loud",
        "isActive": true,
        "timezone": "Asia/Kolkata"
      }
    ]
  }
}

This returns all the organizations filtered by the input OrganizationFilter

Query Parameters

Parameter Type Default Description
filter OrganizationFilter nil filter the list
opts Opts nil limit / offset / sort order options

Return Parameters

Type Description
[Organization] List of organization

Get a specific Organization by ID

query organization($id: ID) {
  organization(id: $id) {
    organization {
      id
      name
      isActive
      timezone
      defaultLanguage {
        id
        label
      }
    }
  }
}

{
  "id": 1
}

The above query returns JSON structured like this:

{
  "data": {
    "organization": {
      "organization": {
        "defaultLanguage": {
          "id": "1",
          "label": "Hindi"
        },
        "id": "1",
        "name": "Default Organization",
        "isActive": true,
        "timezone": "Asia/Kolkata"
      }
    }
  }
}

Get current user's organization details

query organization {
  organization {
    organization {
      id
      name
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID

Return Parameters

Type Description
OrganizationResult Queried organization or Current user's organization

Get Organization Services

query organizationServices() {
  bigquery
  dialogflow
  googleCloudStorage
  funWithFlags
  flowUuidDisplay
  errors {
    key
    message
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "organizationServices": {
      "bigquery": true,
      "dialogflow": false,
      "funWithFlags": true,
      "flowUuidDisplay": false,
      "googleCloudStorage": true
    }
  }
}

Return Parameters

Type Description
organizationServicesResult Queried organization or Current user's organization

Count all Organizations

query countOrganizations($filter: OrganizationFilter) {
  countOrganizations(filter: $filter)
}

{
  "filter": {
    "language": "Hindi"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "countOrganizations": 2
  }
}

Query Parameters

Parameter Type Default Description
filter OrganizationFilter nil filter the list

Return Parameters

Type Description
Int Count of filtered organization

Create an Organization

mutation createOrganization($input:OrganizationInput!) {
  createOrganization(input: $input) {
    organization {
      id
      name
      shortcode
      contact {
        id
      }
      email
      bsp {
        id
        name
      }
      defaultLanguage {
        id
        label
      }
    }
    errors {
      key
      message
    }
  }
}

{
  "input": {
    "shortcode": "new_organization",
    "name": "new organization",
    "contactId": 1,
    "email": "test@test.com",
    "bspId": 1,
    "defaultLanguageId": 1,
    "activeLanguageIds": [1]
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "createOrganization": {
      "errors": null,
      "organization": {
        "contact": {
          "id": "1"
        },
        "defaultLanguage": {
          "id": "1",
          "label": "Hindi"
        },
        "name": "new organization",
        "email": "test@test.com",
        "id": "3",
        "shortcode": "new_organization",
        "bsp": {
          "id": "1",
          "name": "Default Provider"
        }
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
input OrganizationInput required

Return Parameters

Type Description
OrganizationResult The created organization object

Update an Organization

mutation updateOrganization($id: ID!, $input: OrganizationInput!) {
  updateOrganization(id: $id, input: $input) {
    organization {
      id
      name
      shortcode
      sessionLimit
      outOfOffice {
        enabled
        startTime
        endTime
        flowId
        enabledDays {
          id
          enabled
        }
      }
    }
    errors {
      key
      message
    }
  }
}

{
  "id": "1",
  "input": {
    "name": "updated organization display name",
    "sessionLimit": 180,
    "outOfOffice": {
      "enabled": true,
      "enabledDays": [
        {
          "enabled": true,
          "id": 1
        },
        {
          "enabled": true,
          "id": 2
        },
        {
          "enabled": true,
          "id": 3
        },
        {
          "enabled": true,
          "id": 4
        },
        {
          "enabled": true,
          "id": 5
        },
        {
          "enabled": false,
          "id": 6
        },
        {
          "enabled": false,
          "id": 7
        }
      ],
      "endTime": "T19:00:00",
      "flowId": 1,
      "defaultFlowId": 1,
      "startTime": "T09:00:00"
    }
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "updateOrganization": {
      "errors": null,
      "organization": {
        "name": "updated organization display name",
        "id": "1",
        "name": "Glific",
        "sessionLimit": 180,
        "outOfOffice": {
          "enabled": true,
          "enabledDays": [
            {
              "enabled": true,
              "id": 1
            },
            {
              "enabled": true,
              "id": 2
            },
            {
              "enabled": true,
              "id": 3
            },
            {
              "enabled": true,
              "id": 4
            },
            {
              "enabled": true,
              "id": 5
            },
            {
              "enabled": false,
              "id": 6
            },
            {
              "enabled": false,
              "id": 7
            }
          ],
          "endTime": "19:00:00",
          "flowId": "1",
          "startTime": "9:00:00"
        }
      }
    }
  }
}

Enabled days Ids represets weekdays starting from 1 for Monday.

Query Parameters

Parameter Type Default Description
id ID! required
input OrganizationInput required

Return Parameters

Type Description
OrganizationResult The updated organization object

Delete an Organization

mutation deleteOrganization($id: ID!) {
  deleteOrganization(id: $id) {
    errors {
      key
      message
    }
  }
}

{
  "id": "3"
}

The above query returns JSON structured like this:

{
  "data": {
    "deleteOrganization": {
      "errors": null
    }
  }
}

In case of errors, all the above functions return an error object like the below

{
  "data": {
    "deleteOrganization": {
      "errors": [
        {
          "key": "Elixir.Glific.Partners.Organization 3",
          "message": "Resource not found"
        }
      ]
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required

Return Parameters

Type Description
OrganizationResult An error object or empty

Check for attachment support for the given user

query attachmentsEnabled {
  attachmentsEnabled
}

The above query returns JSON structured like this:

{
  "data": {
    "attachmentsEnabled": true
  }
}

Return Parameters

Type Description
Boolean Have we enabled attachment support for this organization

Get List of Timezones

query timezones {
  timezones
}

The above query returns JSON structured like this:


{
  "data": {
    "timezones": [
      "Africa/Abidjan",
      "Africa/Accra",
      "Africa/Addis_Ababa",
      ...
    ]
  }
}

This returns list of timezones

Return Parameters

Type Description
[String] List of timezones

Get List of Organization Status

query organizationStatus {
  organizationStatus
}

The above query returns A list of all the organization status:


{
  "data": {
    "organizationStatus": [
      "INACTIVE",
      "APPROVED",
      "ACTIVE",
      "SUSPENDED",
      "READY_TO_DELETE"
    ]
  }
}

This returns list of timezones

Return Parameters

Type Description
[String] List of status

Subscription for Wallet Balance

subscription organization_subscriptions {
  bsp_balance(organizationId: "1")
}

The above query returns JSON structured like this:

{
  "data": {
    "bspbalance": "{\"balance\":0.426}"
  }
}

Return Parameters

Parameter Type Default Description
JSON with "balance" as name and the amount of remaining balance as value

Subscription for Collection Count

subscription organization_subscriptions {
  collection_count(organizationId: "1")
}

The above query returns JSON structured like this:

{
  "data": {
    "collection": "{
      \"All\": 5,
      \"Not Responded\": 3,
      \"Not replied\": 2,
      \"Optout\": 0,
      \"Unread\": 4
    }"
  }
}

Return Parameters

Parameter Type Default Description
JSON with "collection" as name and array with key as collection count name and value as collection count

Subscription for Simulator release

subscription organization_subscriptions {
  simulator_release(organizationId: "1")
}

The above query returns JSON structured like this:

{
  "data": {
    "simulator_release": "{\"simulator_release\":{\"user_id\":1}"
  }
}

Return Parameters

Parameter Type Default Description
JSON with "simulator_release" as name and array with key as user_id and value as id of user

Organization Objects

Organization

Field Argument Type Description
contact Contact
defaultLanguage Language
activeLanguages [Language]
shortcode String
email String
id ID
name String
bsp Provider
outOfOffice OutOfOffice
newcontactFlowId ID
isActive Boolean
timezone String
sessionLimit Integer (in minutes)
signaturePhrase String
isSuspended Boolean
suspendedUntil DateTime
isFlowUuidDisplay Boolean
insertedAt DateTime
updatedAt DateTime

OrganizationResult

Field Argument Type Description
errors [InputError]
organization Organization

Organization Services Result

Field Argument Type Description
fun_with_flags Boolean
dialogflow Boolean
google_cloud_storage Boolean
bigquery Boolean
errors [InputError]

OutOfOffice

Field Argument Type Description
enabled Boolean
startTime Time
endTime Time
enabledDays [EnabledDay]
flow_id ID

EnabledDay

Field Argument Type Description
id Integer
enabled Boolean

Organization Inputs

OrganizationFilter

Filtering options for organizations

Field Type Description
defaultLanguage String Match the default language
shortcode String Match the shortcode
email String Match the email
name String Match the name
bsp String Match the bsp provider

OrganizationInput

Field Type Description
contactId ID Nullable
name String Unique
defaultLanguageId ID
activeLanguageIds [ID]
shortcode String
email String
bspId ID
outOfOfficeInput OutOfOfficeInput
isActive Boolean
timezone String
sessionLimit Integer (in minutes)
signaturePhrase String

OutOfOfficeInput

Field Argument Type Description
enabled Boolean
startTime Time
endTime Time
enabledDays [EnabledDayInput]
flow_id ID

EnabledDayInput

Field Argument Type Description
id Integer!
enabled Boolean!

Users

Get All Roles

query {
  roles
}

The above query returns JSON structured like this:

{
  "data": {
    "roles": ["none", "staff", "manager", "admin"]
  }
}

This returns all the roles

Return Parameters

Type Description
[Role] List of roles

Get All Users

query users($filter: UserFilter, $opts: Opts) {
  users(filter: $filter, opts:$opts) {
    id
    name
    phone
    roles
    groups {
      label
    }
  }
}

{
  "filter": {
    "name": "Doe"
  },
  "opts": {
    "order": "ASC",
    "limit": 10,
    "offset": 0
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "users": [
      {
        "groups": [],
        "id": "1",
        "name": "John Doe",
        "phone": "+919820198765",
        "roles": ["admin"]
      },
      {
        "groups": [
          {
            "label": "First Group"
          }
        ],
        "id": "2",
        "name": "Jane Doe",
        "phone": "+918820198765",
        "roles": ["staff", "admin"]
      }
    ]
  }
}

This returns all the users filtered by the input UserFilter

Query Parameters

Parameter Type Default Description
filter UserFilter nil filter the list
opts Opts nil limit / offset / sort order options

Return Parameters

Type Description
[User] List of users

Get a specific User by ID

query user($id: ID!) {
  user(id: $id) {
    user {
      id
      name
      phone
      roles
      language {
        isActive
        label
        labelLocale
      }
    }
  }
}

{
  "id": 1
}

The above query returns JSON structured like this:

{
  "data": {
    "user": {
      "user": {
        "id": "1",
        "name": "John Doe",
        "phone": "+919820198765",
        "roles": ["admin"],
        "language": {
          "isActive": true,
          "label": "English",
          "labelLocale": "English"
        }
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
ID ID nil

Return Parameters

Type Description
UserResult Queried User

Get Current User

query currentUser {
  currentUser {
    user {
      id
      name
      phone
      roles
      organization {
        activeLanguages {
          label
        }
      }
    }
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "user": {
      "user": {
        "id": "1",
        "name": "John Doe",
        "phone": "+919820198765",
        "roles": ["Admin"],
        "organization": {
          "activeLanguages": [
            {
              "label": "English"
            }
          ]
        }
      }
    }
  }
}

Return Parameters

Type Description
UserResult Current User

Count all Users

query countUsers($filter: UserFilter) {
  countUsers(filter: $filter)
}

{
  "filter": {
    "name": "John"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "countUsers": 1
  }
}

Query Parameters

Parameter Type Default Description
filter UserFilter nil filter the list

Return Parameters

Type Description
Int Count of filtered users

Update a User

mutation updateUser($id: ID!, $input: UserInput!) {
  updateUser(id: $id, input: $input) {
    user {
      id
      name
      phone
      roles
      groups {
        label
      }
    }
    errors {
      key
      message
    }
  }
}

{
  "id": "2",
  "input": {
    "name": "Updated Name",
    "roles": [
      "admin"
    ],
    "groupIds": [
      1,
      2
    ]
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "updateUser": {
      "errors": null,
      "user": {
        "groups": [
          {
            "label": "First Group"
          },
          {
            "label": "Poetry Group"
          }
        ],
        "id": "2",
        "name": "Updated Name",
        "phone": "919876543210",
        "roles": ["admin"]
      }
    }
  }
}

In case of errors, above function returns an error object like the below

{
  "data": {
    "updateUser": {
      "errors": [
        {
          "key": "roles",
          "message": "has an invalid entry"
        }
      ],
      "user": null
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required
input UserInput required
groupIds [ID] required

Return Parameters

Type Description
UserResult The updated user object

Update Current User Details

mutation updateCurrentUser($input:CurrentUserInput!) {
  updateCurrentUser(input: $input) {
    user {
      id
      name
    }
    errors {
      key
      message
    }
  }
}

{
  "input": {
    "name": "Updated Name"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "updateCurrentUser": {
      "errors": null,
      "user": {
        "id": "2",
        "name": "Updated Name"
      }
    }
  }
}

Current User can update only the name and password, but not the phone number

Update Current User Password

mutation updateCurrentUser($input:CurrentUserInput!) {
  updateCurrentUser(input: $input) {
    user {
      id
      name
    }
    errors {
      key
      message
    }
  }
}

{
  "input": {
    "name": "Updated Name",
    "otp": "340606",
    "password": "new_password"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "updateCurrentUser": {
      "errors": null,
      "user": {
        "id": "2",
        "name": "Updated Name"
      }
    }
  }
}

In case of otp errors, above function returns an error object like the below

{
  "data": {
    "updateCurrentUser": {
      "errors": [
        {
          "key": "OTP",
          "message": "does_not_exist"
        }
      ],
      "user": null
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required
input CurrentUserInput required

Return Parameters

Type Description
UserResult The updated user object

Delete a User

mutation deleteUser($id: ID!) {
  deleteUser(id: $id) {
    errors {
      key
      message
    }
  }
}

{
  "id": "2"
}

The above query returns JSON structured like this:

{
  "data": {
    "deleteUser": {
      "errors": null
    }
  }
}

In case of errors, all the above functions return an error object like the below

{
  "data": {
    "deleteUser": {
      "errors": [
        {
          "key": "Elixir.Glific.Users.User 2",
          "message": "Resource not found"
        }
      ]
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required

Return Parameters

Type Description
UserResult An error object or empty

User Objects

User

Field Argument Type Description
id ID
contact Contact
language Language
name String
phone String
roles [String]
groups [Group]
isRestricted Boolean
insertedAt DateTime
updatedAt DateTime

UserResult

Field Argument Type Description
errors [InputError]
user User

Role

Field Argument Type Description
id ID
label String

User Inputs

UserFilter

Filtering options for users

Field Type Description
name String Match the name
phone String Match the phone

UserInput

Field Type Description
name String
roles [String]
groupIds [ID]
languageId ID
isRestricted Boolean

CurrentUserInput

Field Type Description
name String
otp String
password String
languageId ID

Contacts

Get All Contacts

query contacts($filter: ContactFilter, $opts: Opts) {
  contacts(filter: $filter, opts:$opts) {
    id
    name
    optinTime
    optoutTime
    optinMethod
    optoutMethod
    phone
    maskedPhone
    bspStatus
    status
    tags {
      id
      label
    }
    groups {
      id
      label
    }
  }
}

{
  "filter": {
    "name": "Default Receiver"
  },
  "opts": {
    "order": "ASC",
    "limit": 10,
    "offset": 0
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "contacts": [
      {
        "groups": [],
        "id": "2",
        "name": "Default Receiver",
        "optinTime": null,
        "optoutTime": null,
        "optinMethod": null,
        "optoutMethod": null,
        "phone": "917834811231",
        "maskedPhone": "9178******31",
        "bspStatus": "SESSION_AND_HSM",
        "status": "VALID",
        "tags": []
      }
    ]
  }
}

This returns all the contacts filtered by the input ContactFilter

Query Parameters

Parameter Type Default Description
filter ContactFilter nil filter the list
opts Opts nil limit / offset / sort order options

Return Parameters

Type Description
[Contact] List of contacts

Other filters on Contacts

query contacts($filter: ContactFilter, $opts: Opts) {
  contacts(filter: $filter, opts: $opts) {
    id
    name
    groups {
      id
    }
    tags {
      id
    }
  }
}

{
  "filter": {
    "includeGroups": [
      1,
      2
    ],
    "includeTags": [
      1
    ]
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "contacts": [
      {
        "groups": [
          {
            "id": "1"
          },
          {
            "id": "2"
          }
        ],
        "id": "1",
        "name": "Glific Admin",
        "phone": "917834811114",
        "tags": [
          {
            "id": "1"
          }
        ]
      },
      {
        "groups": [
          {
            "id": "1"
          }
        ],
        "id": "2",
        "name": "Default receiver",
        "phone": "917834811231",
        "tags": [
          {
            "id": "1"
          }
        ]
      }
    ]
  }
}

Return Parameters

Type Description
[Contact] List of contacts

Get All Blocked Contacts

query contacts($filter: ContactFilter, $opts: Opts) {
  contacts(filter: $filter, opts:$opts) {
    id
    phone
    status
  }
}

{
  "filter": {
    "status": "BLOCKED"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "contacts": [
      {
        "id": "5",
        "phone": "7739920221",
        "status": "BLOCKED"
      }
    ]
  }
}

Return Parameters

Type Description
[Contact] List of contacts

Get a specific Contact by ID

query contact($id: ID!) {
  contact(id: $id) {
    contact {
      id
      name
      optinTime
      optoutTime
      phone
      bspStatus
      status
      tags {
        id
        label
      }
      lastMessageAt
      language {
        label
      }
      fields
      settings
      history {
        eventType
        eventLabel
        eventMeta
      }
    }
  }
}

{
  "id": 5
}

The above query returns JSON structured like this:

{
  "data": {
    "contact": {
      "contact": {
        "fields": "{\"name\":{\"value\":\"default\",\"type\":\"string\",\"inserted_at\":\"2020-08-28T15:34:49.192659Z\"},\"age_group\":{\"value\":\"19 or above\",\"type\":\"string\",\"inserted_at\":\"2020-08-28T15:34:55.657740Z\"}}",
        "id": "5",
        "language": {
          "label": "Hindi"
        },
        "lastMessageAt": "2020-08-28T13:15:19Z",
        "name": "Default receiver",
        "optinTime": "2020-08-28T13:15:19Z",
        "optoutTime": null,
        "phone": "917834811231",
        "bspStatus": "SESSION_AND_HSM",
        "settings": null,
        "status": "VALID",
        "tags": [],
        "history": [
          {
            "eventLabel": "All contact flows are ended.",
            "eventMeta": "{}",
            "eventType": "contact_flow_ended_all"
          },
          {
            "eventLabel": "Flow (Contact History Flows) started for the contact",
            "eventMeta": "{\"flow_name\":\"Contact History Flows\",\"flow_id\":14,\"context_id\":6}",
            "eventType": "contact_flow_started"
          },
          {
            "eventLabel": "Value for new_field is updated to Value 1",
            "eventMeta": "{\"value\":\"Value 1\",\"old_value\":{\"value\":\"value 2\",\"type\":\"string\",\"label\":\"new_field\",\"inserted_at\":\"2021-12-02T09:12:12.007578Z\"},\"new_value\":\"Value 1\",\"label\":\"new_field\",\"field\":\"new_field\"}",
            "eventType": "contact_fields_updated"
          }
        ]
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
ID ID nil

Return Parameters

Type Description
ContactResult Queried Contact

Count all Contacts

query countContacts($filter: ContactFilter) {
  countContacts(filter: $filter)
}

{
  "filter": {
    "status": "VALID"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "countContacts": 6
  }
}

Query Parameters

Parameter Type Default Description
filter ContactFilter nil filter the list

Return Parameters

Type Description
Int Count of filtered contacts

Create a Contact

mutation createContact($input:ContactInput!) {
  createContact(input: $input) {
    contact {
      id
      name
      optinTime
      optoutTime
      phone
      bspStatus
      status
      tags {
        id
        label
      }
    }
    errors {
      key
      message
    }
  }
}

{
  "input": {
    "name": "This is a new contact for this example",
    "phone": "9876543232"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "createContact": {
      "contact": {
        "id": "15",
        "name": null,
        "optinTime": null,
        "optoutTime": null,
        "phone": "9876543232",
        "bspStatus": "SESSION",
        "status": null,
        "tags": []
      },
      "errors": null
    }
  }
}

Query Parameters

Parameter Type Default Description
input ContactInput required

Return Parameters

Type Description
ContactResult The created contact object

Update a Contact

mutation updateContact($id: ID!, $input:ContactInput!) {
  updateContact(id: $id, input: $input) {
    contact {
      id
      name
      bspStatus
      status
      fields
      settings
      language{
        label
      }
    }
    errors {
      key
      message
    }
  }
}

{
  "id": "5",
  "input": {
    "name": "This is a updated contact for this example",
    "fields": "{\"name\":{\"value\":\"default\",\"type\":\"string\",\"inserted_at\":\"2020-08-29T05:35:38.298593Z\"},\"age_group\":{\"value\":\"19 or above\",\"type\":\"string\",\"inserted_at\":\"2020-08-29T05:35:46.623892Z\"}}",
    "languageId": 2
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "updateContact": {
      "contact": {
        "fields": "{\"name\":{\"value\":\"default\",\"type\":\"string\",\"inserted_at\":\"2020-08-29T05:35:38.298593Z\"},\"age_group\":{\"value\":\"19 or above\",\"type\":\"string\",\"inserted_at\":\"2020-08-29T05:35:46.623892Z\"}}",
        "id": "5",
        "language": {
          "label": "English"
        },
        "name": "This is a updated contact for this example",
        "bspStatus": "SESSION_AND_HSM",
        "settings": null,
        "status": "VALID"
      },
      "errors": null
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required
input ContactInput required

Return Parameters

Type Description
ContactResult The updated contact object

Block a Contact

mutation updateContact($id: ID!, $input:ContactInput!) {
  updateContact(id: $id, input: $input) {
    contact {
      id
      phone
      status
    }
  }
}

{
  "id": "5",
  "input": {
    "status": "BLOCKED"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "updateContact": {
      "contact": {
        "name": "This is a updated contact for this example",
        "phone": "7739920221",
        "status": "BLOCKED"
      },
      "errors": null
    }
  }
}

Return Parameters

Type Description
ContactResult The updated contact object

UnBlock a Contact

mutation updateContact($id: ID!, $input:ContactInput!) {
  updateContact(id: $id, input: $input) {
    contact {
      id
      phone
      status
    }
  }
}

{
  "id": "5",
  "input": {
    "status": "VALID"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "updateContact": {
      "contact": {
        "name": "This is a updated contact for this example",
        "phone": "7739920221",
        "status": "VALID"
      },
      "errors": null
    }
  }
}

Return Parameters

Type Description
ContactResult The updated contact object

Delete a Contact

mutation deleteContact($id: ID!) {
  deleteContact(id: $id) {
    errors {
      key
      message
    }
  }
}

{
  "id": "26"
}

The above query returns JSON structured like this:

{
  "data": {
    "deleteContact": {
      "errors": null
    }
  }
}

In case of errors, all the above functions return an error object like the below

{
  "data": {
    "deleteContact": {
      "errors": [
        {
          "key": "Elixir.Glific.Contacts.Contact 26",
          "message": "Resource not found"
        }
      ]
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required

Return Parameters

Type Description
ContactResult An error object or empty

Get contact's location

query contactLocation($id: ID!) {
  contactLocation(id: $id) {
    latitude
    longitude
  }
}

{
  "id": "2"
}

The above query returns JSON structured like this:

{
  "data": {
    "contactLocation": {
      "latitude": -30.879910476061603,
      "longitude": 156.21478312951263
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID!

Return Parameters

Type Description
Location A location object

Optin a Contact

mutation optinContact($phone: String!, $name: String) {
  optinContact(phone: $phone, name: $name) {
    contact {
      id
      phone
      name
      lastMessageAt
      optinTime
      bspStatus
    }
    errors {
      key
      message
    }
  }
}

{
  "phone": "917834811119",
  "name": "contact name"
}

The above query returns JSON structured like this:

{
  "data": {
    "optinContact": {
      "contact": {
        "bspStatus": "HSM",
        "id": "100",
        "lastMessageAt": null,
        "name": "contact name",
        "optinTime": "2020-11-25T16:12:18Z",
        "phone": "917834811119"
      },
      "errors": null
    }
  }
}

Query Parameters

Parameter Type Default Description
phone String! required
name String

Return Parameters

Type Description
ContactResult contact object

Get a simulator contact

Gets a simulator contact for the logged in user. We are currently returning the same simulator for the same user ID. We will revisit this protocol and potentially pass the user token instead to get a different simulator for different sessions for the same logged in user.

query simulatorGet() {
  simulatorGet {
    id
    name
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "simulatorGet": {
      "id": "2",
      "name": "Simulator"
    }
  }
}

OR if no simulator is available

{
  "data": {
    "simulatorGet": null
  }
}

Query Parameters

Parameter Type Default Description

Return Parameters

Type Description
Contact A contact object

Release a simulator contact

Releases a simulator contact for the logged in user if one exists. The system also releases the simulator when it has been idle for more than 10 minutes and there is a request for a simulator

query simulatorRelease {
  simulatorRelease {
    id
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "simulatorRelease": null
  }
}

Query Parameters

Parameter Type Default Description

Return Parameters

Type Description

Get All Contact History

query ContactHistory($filter: ContactsHistoryFilter, $opts: Opts) {
    contactHistory(filter: $filter, opts: $opts) {
      eventDatetime
      eventLabel
      eventMeta
      eventType
      id
      insertedAt
      updatedAt
    }
  }


{
  "opts": {
    "order": "ASC",
    "limit": 10,
    "offset": 0
  },
  "filter": {
    "contactId": 1
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "contactHistory": [
      {
        "eventDatetime": "2021-12-07T12:12:50Z",
        "eventLabel": "All contact flows are ended.",
        "eventMeta": "{}",
        "eventType": "contact_flow_ended_all",
        "id": "106",
        "insertedAt": "2021-12-07T12:12:51.000000Z",
        "updatedAt": "2021-12-07T12:12:51.000000Z"
      },
      {
        "eventDatetime": "2021-12-07T12:12:50Z",
        "eventLabel": "Flow Started",
        "eventMeta": "{\"flow\":{\"uuid\":\"3fa22108-f464-41e5-81d9-d8a298854429\",\"name\":\"Help Workflow\",\"id\":1},\"context_id\":70}",
        "eventType": "contact_flow_started",
        "id": "107",
        "insertedAt": "2021-12-07T12:12:51.000000Z",
        "updatedAt": "2021-12-07T12:12:51.000000Z"
      },
      {
        "eventDatetime": "2021-12-07T12:12:50Z",
        "eventLabel": "Flow Ended:",
        "eventMeta": "{\"flow\":{\"uuid\":\"3fa22108-f464-41e5-81d9-d8a298854429\",\"name\":\"Help Workflow\",\"id\":1},\"context_id\":70}",
        "eventType": "contact_flow_ended",
        "id": "108",
        "insertedAt": "2021-12-07T12:12:51.000000Z",
        "updatedAt": "2021-12-07T12:12:51.000000Z"
      }
    ]
  }
}

This returns all the contact history for the contact filtered by the input contactHistoryFilter

Query Parameters

Parameter Type Default Description
filter contactHistoryFilter nil filter the list
opts Opts nil limit / offset / sort order options

Count all ContactHistory

query countContactHistory($filter: ContactsHistoryFilter) {
  countContactHistory(filter: $filter)
}


{
  "filter": {
    "contact_id": 1
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "countContactHistory": 3
  }
}

Query Parameters

Parameter Type Default Description
filter contactHistoryFilter nil filter the list

Contact Objects

Contact

Field Argument Type Description
id ID
name String
optinTime DateTime
optoutTime DateTime
optinMethod String
optoutMethod String
phone String
maskedPhone String
bspStatus ContactProviderStatusEnum
status ContactStatusEnum
isOrgRead Boolean
isOrgReplied Boolean
isContactReplied Boolean
LastMessageNumber Integer
fields Json
settings Json
lastMessageAt DateTime
lastCommunicationAt DateTime
insertedAt DateTime
updatedAt DateTime
language Language
tags [Tag]
groups [Group]
history History

History

Field Argument Type Description
id ID
event_type Event Type
event_label Event Label
event_meta Event Meta
event_datetime Event DateTime

contactHistoryFilter

Field Argument Type Description
contact_id ID
event_type Event Type
event_label Event Label

Location

Field Argument Type Description
latitude Float
longitude Float

ContactResult

Field Argument Type Description
contact Contact
errors [InputError]

Contact Inputs

ContactFilter

Filtering options for contacts

Field Type Description
name String Match the name
phone String Match the phone
bspStatus ContactProviderStatusEnum
status ContactStatusEnum Match the status
includeTags [id] Match if contact has a tag of includeTags list
includeGroups [id] Match if contact is mapped in a group of includeGroups list

ContactInput

Field Type Description
name String
phone String
languageId ID
bspStatus ContactProviderStatusEnum
status ContactStatusEnum
fields Json
settings Json

Tags

Get All Tags

query tags($filter: TagFilter, $opts: Opts) {
  tags(filter: $filter, opts:$opts) {
    id
    label
    language {
      id
      label
    }
  }
}

{
  "opts": {
    "order": "ASC",
    "limit": 10,
    "offset": 0
  },
  "filter": {
    "languageId": 1
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "tags": [
      {
        "id": "18",
        "label": "Child",
        "language": {
          "id": "2",
          "label": "English"
        }
      },
      {
        "id": "3",
        "label": "Compliment",
        "language": {
          "id": "2",
          "label": "English"
        }
      },
      {
        "id": "2",
        "label": "Contacts",
        "language": {
          "id": "2",
          "label": "English"
        }
      }
    ]
  }
}

This returns all the tags for the organization filtered by the input TagFilter

Query Parameters

Parameter Type Default Description
filter TagFilter nil filter the list
opts Opts nil limit / offset / sort order options

Get a specific Tag by ID

query tag($id: ID!) {
  tag(id: $id) {
    tag {
      id
      label
      language {
        id
        label
      }
    }
  }
}

{
  "id": 2
}

The above query returns JSON structured like this:

{
  "data": {
    "tag": {
      "tag": {
        "id": "2",
        "label": "Contacts",
        "language": {
          "id": "2",
          "label": "English"
        }
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
ID ID nil

Count all Tags

query countTags($filter: TagFilter) {
  countTags(filter: $filter)
}

{
  "filter": {
    "languageId": 2
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "countTags": 22
  }
}

Query Parameters

Parameter Type Default Description
filter TagFilter nil filter the list

Create a Tag

mutation createTag($input:TagInput!) {
  createTag(input: $input) {
    tag {
      id
      label
      language {
        id
        label
      }
      description
    }
    errors {
      key
      message
    }
  }
}

{
  "input": {
    "label": "This is a new tag for this example",
    "shortcode": "new-tag",
    "description": "This is a cool description",
    "languageId": "1"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "createTag": {
      "errors": null,
      "tag": {
        "description": "This is a cool description",
        "id": "26",
        "label": "This is a new tag for this example",
        "language": {
          "id": "1",
          "label": "Hindi"
        }
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
input TagInput required

Return Parameters

Type Description
TagResult The created tag object

Update a Tag

mutation updateTag($id: ID!, $input:TagInput!) {
  updateTag(id: $id, input: $input) {
    tag {
      id
      label
      language {
        id
        label
      }
      description
    }
    errors {
      key
      message
    }
  }
}

{
  "id": "26",
  "input": {
    "label": "This is a update tag for this example",
    "description": "This is a updated cool description",
    "languageId": "2"
  }
}```

> The above query returns JSON structured like this:

```json
{
  "data": {
    "updateTag": {
      "errors": null,
      "tag": {
        "description": "This is a updated cool description",
        "id": "26",
        "label": "This is a update tag for this example",
        "language": {
          "id": "2",
          "label": "English"
        }
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required
input TagInput required

Return Parameters

Type Description
TagResult The updated tag object

Delete a Tag

mutation deleteTag($id: ID!) {
  deleteTag(id: $id) {
    errors {
      key
      message
    }
  }
}

{
  "id": "26"
}

The above query returns JSON structured like this:

{
  "data": {
    "deleteTag": {
      "errors": null,
      "tag": null
    }
  }
}

In case of errors, all the above functions return an error object like the below

{
  "data": {
    "deleteTag": {
      "errors": [
        {
          "key": "Elixir.Glific.Tags.Tag 29",
          "message": "Resource not found"
        }
      ]
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required

Return Parameters

Parameter Type Default Description
TagResult An error object or empty

Remove unread status from contact

mutation markContactMessagesAsRead($contactId : Gid!) {
  markContactMessagesAsRead(contactId: $contactId)
}

{
  "contactId": "26"
}

The above query returns the same contactID back

{
  "data": {
    "markContactMessagesAsRead": [
       "26"
    ]
  }
}

Query Parameters

Parameter Type Default Description
contactId Gid! required

Return Parameters

Parameter Type Default Description
Contact ID The same contact ID or an error object

Tag Objects

Tag

Field Argument Type Description
description String
id ID
isActive Boolean
isReserved Boolean
keywords [String]
label String
shortcode String
language Language
parent Tag
insertedAt DateTime
updatedAt DateTime

TagResult

Field Argument Type Description
errors [InputError]
tag Tag

Tag Inputs

TagFilter

Filtering options for tags

Field Type Description
description String Match the description
isActive Boolean Match the active flag
isReserved Boolean Match the reserved flag
label String Match the label
language String Match a language
languageId Int Match a language id
parent String Match the parent
parentId Int Match the parent

TagInput

Field Type Description
description String
color_code String Default: #0C976D
isActive Boolean
isReserved Boolean
keywords [String]
label String
languageId ID
parentId ID

Contact Tag

Join table between contacts and tags

Create Contact Tag

mutation createContactTag($input: ContactTagInput!) {
  createContactTag(input: $input) {
    contactTag {
      id
      contact {
        id
        name
      }
      tag {
        id
        label
        parent {
          id
          label
        }
      }
    }
    errors {
      key
      message
    }
  }
}

{
  "input": {
    "contactId": 2,
    "tagId": 20
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "createContactTag": {
      "contactTag": {
        "contact": {
          "id": "2",
          "name": "Default receiver"
        },
        "id": "8",
        "tag": {
          "id": "20",
          "label": "Participant",
          "parent": {
            "id": "2",
            "label": "Contacts"
          }
        }
      },
      "errors": null
    }
  }
}

Query Parameters

Parameter Type Default Description
input ContactTagInput required

Return Parameters

Type Description
ContactTagResult The created contact tag object

Update a Contact with tags to be added and tags to be deleted

mutation updateContactTags($input: ContactTagsInput!) {
  updateContactTags(input: $input) {
    contactTags {
      id
      contact {
        name
      }
      tag {
        label
      }
    }
    numberDeleted
  }
}
{
  "input": {
    "contactId": 2,
    "addTagIds": [3, 6],
    "deleteTagIds": [7, 8]
  }
}

The above query returns JSON structured like this: json { "data": { "updateContactTags": { "numberDeleted": 2, "contactTags": [ { "id": "29", "tag": { "label": "Thank You" }, "contact": { "name": "Default receiver" } }, { "id": "28", "tag": { "label": "Good Bye" }, "contact": { "name": "Default receiver" } } ] } } }

Query Parameters

Parameter Type Default Description
input ContactTagsInput required

Return Parameters

Type Description
contactTags The list of contact tags added
integer The number of contact tags deleted

Subscription for Create Contact Tag

subscription {
  createdContactTag {
    contact{
      id
    }
    tag{
      id
    }
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "createdContactTag": {
      "contact": {
        "id": "194"
      },
      "tag": {
        "id": "194"
      }
    }
  }
}

Return Parameters

Parameter Type Default Description
ContactTag An error or object

Subscription for Delete Contact Tag

subscription {
  deletedContactTag() {
    contact{
      id
    }
    tag{
      id
    }
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "deletedContactTag": {
      "contact": {
        "id": "194"
      },
      "tag": {
        "id": "194"
      }
    }
  }
}

Return Parameters

Parameter Type Default Description
ContactTag An error or object

ContactTag Objects

ContactTag

Field Argument Type Description
id ID
contact Contact
tag Tag
value String

TemplateTags

Field Argument Type Description
contactTags [ContactTag]

ContactTagResult

Field Argument Type Description
contactTag ContactTag
errors [InputError]

ContactTag Inputs

ContactTagInput

Field Type Description
contactId ID
tagId ID

ContactTagsInput

Field Type Description
ContactId Id
AddTagIds [Id]!
DeleteTagIds [Id]!

Messages Tags

Create a Message Tag

mutation createMessageTag($input:MessageTagInput!) {
  createMessageTag(input: $input) {
    messageTag {
      id
      value
      message {
        id
        body
      }

      tag {
        id
        label
      }
    }
    errors {
      key
      message
    }
  }
}

{
  "input": {
    "messageId": 2,
    "tagId": 3
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "messageTag": {
      "errors": null,
      "messageTag": {
        "id": 10,
        "value": "1",
        "message": {
          "id" : 2,
          "body": "one"
        },
        "tag": {
          "id" : 3,
          "label": "Numeric"
        }
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
input MessageTagInput required

Return Parameters

Type Description
MessageTagResult The created message tag object

Update a Message with tags to be added and tags to be deleted

mutation updateMessageTags($input: MessageTagsInput!) {
  updateMessageTags(input: $input) {
    messageTags {
       id,
      message {
        body
      }

      tag {
        label
      }

    }
    errors {
      key
      message
    }
  }
}

{
  "input": {
    "messageId": 2,
    "addTagIds": [3, 4, 5, 6]
    "deleteTagIds": [7, 8]
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "updateMessageTags": {
      "errors": null,
      "messageTags": {
         {
          "id": "11476",
          "message": {
            "body": "Thank you"
          },
          "tag": {
            "label": "Good Bye"
          }
        },

        {
          "id": "11475",
          "message": {
            "body": "message body for order test"
          },
          "tag": {
            "label": "Compliment"
          }
        }

      },
      numberDeleted: 2,
    }
  }
}

Query Parameters

Parameter Type Default Description
input MessageTagsInput required

Return Parameters

Type Description
messageTags The list of tag messages added
integer The number of messages deleted

Subscription for Create Message Tag

subscription {
  createdMessageTag {
    message{
      id
    }
    tag{
      id
    }
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "createdMessageTag": {
      "message": {
        "id": "194"
      },
      "tag": {
        "id": "194"
      }
    }
  }
}

Return Parameters

Parameter Type Default Description
Message An error or object

Subscription for Delete Message Tag

subscription {
  deletedMessageTag() {
    message{
      id
    }
    tag{
      id
    }
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "deletedMessageTag": {
      "message": {
        "id": "194"
      },
      "tag": {
        "id": "194"
      }
    }
  }
}

Return Parameters

Parameter Type Default Description
MessageTags An error or object

Message Tag Objects

MessageTag

Field Argument Type Description
id ID
value String
message Message
tag Tag

MessageTags

Field Argument Type Description
messageTags [MessageTag]

MessageTagResult

Field Argument Type Description
errors [InputError]
MessageTag MessageTag

Message Tag Inputs

MessageTagInput

Field Type Description
MessageId Id
TagId Id

MessageTagsInput

Field Type Description
MessageId Id
AddTagIds [Id]!
DeleteTagIds [Id]!

Search

Search Contacts and Conversations

query search(  $saveSearchInput: SaveSearchInput,
  $searchFilter: SearchFilter!, $contactOpts: Opts!, $messageOpts: Opts!) {

  search(filter: $searchFilter, saveSearchInput: $saveSearchInput, contactOpts: $contactOpts, messageOpts: $messageOpts) {

    messages {
      id,
      body,
      tags{
        label
      }
    }

    contact {
      name
    }
  }
}

{
  "saveSearchInput": {
      "label": "Save with this name",
      "shortcode": "SaveName"
  },

  "searchFilter": {
    "includeTags": ["17"],
    "includeGroups": ["1"],
    "includeUsers": ["1"],
    "term": "def",
    "dateRange": {
      "to": "2020-08-10",
      "from": "2020-08-12"
    }
  },
  "messageOpts": {
    "limit": 3,
    "order": "ASC"
  },
  "contactOpts": {
    "order": "DESC",
    "limit": 1
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "search": [
      {
        "contact": {
          "name": "Default receiver"
        },
        "messages": [
          {
            "body": "Architecto est soluta non dignissimos.",
            "id": "4",
            "tags": []
          },
          {
            "body": "ZZZ message body for order test",
            "id": "2",
            "tags": [
              {
                "label": "Compliment"
              },
              {
                "label": "Good Bye"
              },
              {
                "label": "Greeting"
              },
              {
                "label": "Thank You"
              }
            ]
          },
          {
            "body": "Omnis architecto qui pariatur autem minima.",
            "id": "3",
            "tags": []
          }
        ]
      }
    ]
  }
}

This returns a list of conversations that match the term and filters Conversation

Query Parameters

Parameter Type Default Description
filter SearchFilter nil filter the list
saveSearchInput SaveSearchInput nil filter the list. The label and other parameter should be available.
messageOpts Opts nil limit / offset message options
contactOpts Opts nil limit / offset contact options

Search for a multiple section based on term

query searchMulti( $searchFilter: SearchFilter!, $contactOpts: Opts!, $messageOpts: Opts!) {

  searchMulti(filter: $searchFilter, contactOpts: $contactOpts, messageOpts: $messageOpts) {
    contacts {
        body
        contact {
            name
        }
      }
      messages {
        body
        contact {
            name
        }
      }

      tags {
        body
        contact {
            name
        }

        tag {
          label
        }
      }
  }
}

{
  "searchFilter": {
    "term": "def"
  },
  "messageOpts": {
    "limit": 3,
    "order": "ASC"
  },
  "contactOpts": {
    "order": "DESC",
    "limit": 1
  }
}

The above query returns JSON structured like this:

{
  "data": {
     "searchMulti": [
      {
        "contacts": {
          {
            "body": "Architecto est soluta non dignissimos.",
            "contact": {
              "name": "Default receiver"
            }
          }
        },
        "messages": [
          {
            "body": "Architecto est defulat non dignissimos.",
            "contact": {
              "name": "Some contact name"
            }
          }
        ],

        "tags": [
          {
            "body": "Architecto est  non dignissimos.",
            "contact": {
              "name": "Any contact name"
            },
            "tag": {
              "label": "default tag"
            }
          }
        ]
      }
    ]
  }
}

This returns a list of messages filtered in 3 sections SearchMulti

Query Parameters

Parameter Type Default Description
filter SearchFilter nil filter the list
messageOpts Opts nil limit / offset message options
contactOpts Opts nil limit / offset contact options

Saved Search Execution

Runs a search as specified by a saved search. Can optionally send in a string to replace the saved search input string.

query search(
  $searchFilter: SearchFilter!, $contactOpts: Opts!, $messageOpts: Opts!) {

  search(filter: $searchFilter, contactOpts: $contactOpts, messageOpts: $messageOpts) {

    messages {
      id,
      body,
      tags{
        label
      }
    }

    contact {
      name
    }
  }
}

{
  "searchFilter": {
    "savedSearchID": "17",
    "term": "def",
  },
  "messageOpts": {
    "limit": 3,
    "order": "ASC"
  },
  "contactOpts": {
    "order": "DESC",
    "limit": 1
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "search": [
      {
        "contact": {
          "name": "Default receiver"
        },
        "messages": [
          {
            "body": "ZZZ message body for order test",
            "id": "2",
            "tags": [
              {
                "label": "Compliment"
              },
              {
                "label": "Good Bye"
              },
              {
                "label": "Greeting"
              },
              {
                "label": "Thank You"
              }
            ]
          },
          {
            "body": "Omnis architecto qui pariatur autem minima.",
            "id": "3",
            "tags": []
          }
        ]
      }
    ]
  }
}

This returns a list of conversations that match the term and filters Conversation

Saved Search Count

Returns the total number of contacts that match a saved search

query savedSearchCount($id: ID!, $term: String) {
  savedSearchCount(id: $id, term: $term)
}


{
  "id": 4
}
{
  "data": {
    "savedSearchCount": 2
  }
}

Returns a count of the number of contacts returned when executing the saved search.

Query Parameters

Parameter Type Default Description
id ID required Saved search ID
term String nil optional keyword to add to saved search

Search Objects

SearchFilter

Field Argument Type Description
Term String
Status String Message Status - Unread / Not replied / Not Responded / Optout
IncludeTags [Gid]
IncludeLabels [Gid]
IncludeGroups [Gid]
SearchGroup [Boolean] When enabled, we retrieve messages sent to a group. IncludeGroups is the only filter used in this case.
IncludeUsers [Gid]
DateRange [DateRange]
SaveSearchID ID
GroupLabel String

SaveSearchInput

Field Argument Type Description
label String
shortcode String

daterange

Field Argument Type Description
From Date (Y-M-d)
to Date(Y-M-d)

searchmulti

Field Argument Type Description
Contacts [Message] A list of messages filtered by message's contact name and phone
Messages [Message] A list of messages filtered by message's body
Tags [Message] A list of messages filtered by message's tag label and shortcode

Saved Searches

Get All Saved Searches

query savedSearches($filter: SavedSearchFilter!, $opts: Opts) {
  savedSearches(filter: $filter, opts: $opts) {
    id
    label
    shortcode
    args
    count
  }
}

{
  "filter": {
    "label": "conv"
  },
  "opts": {
    "order": "ASC",
    "offset": 0,
    "limit": 1
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "savedSearches": [
      {
        "args": "{
          \"term\":\"\",
          \"messageOpts\":{\"limit\":5},
          \"filter\":{\"includeTags\":[\"10\"]},
          \"contactOpts\":{\"limit\":10}
        }",
        "id": "1",
        "label": "All unread conversations",
        "shortcode": "Unread",
        "count": 4
      }
    ]
  }
}

This returns all the saved searches for the organization filtered by the input SavedSearchFilter

Query Parameters

Parameter Type Default Description
filter SavedSearchFilter nil filter the list
opts Opts nil limit / offset / sort order options

Count all Saved Searches

query countSavedSearches($filter: SavedSearchFilter) {
  countSavedSearches(filter: $filter)
}

{
  "filter": {
    "label": "Conversations read but not replied"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "countSavedSearches": 1
  }
}

Query Parameters

Parameter Type Default Description
filter SavedSearchFilter nil filter the list

Get a specific Saved Search by ID

query savedSearch($id: ID!) {
  savedSearch(id: $id) {
    savedSearch {
      id
      label
      count
    }
  }
}

{
  "id": 2
}

The above query returns JSON structured like this:

{
  "data": {
    "savedSearch": {
      "savedSearch": {
        "id": "2",
        "label": "All Read and Not replied messages",
        "count": 0
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
ID ID

Get a Collection Count Stats for organization

query search_queries {
  collectionStats(organizationId: "1")
}

The above query returns JSON structured like this:

{
  "data": {
    "collectionStats": "{\"1\":{\"Unread\":4,\"Optout\":0,\"Not replied\":2,\"Not Responded\":2,\"All\":4}}"
  }
}

Query Parameters

Parameter Type Default Description
id ID! required

Return Parameters

Parameter Type Default Description
JSON with "organization_id" as name and collection count as value
mutation createSavedSearch($input: SavedSearchInput!) {
  createSavedSearch(input: $input) {
    savedSearch {
      id
      label
      shortcode
      args
    }
    errors {
      key
      message
    }
  }
}

{
  "input": {
    "label": "This is a saved search",
    "shortcode": "Save Search"
    "args": "{"term": "\Save this search\"}"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "savedSearch": {
      "errors": null,
      "savedSearch": {
        "id": "26",
        "label": "This is a saved search",
        "shortcode": "Save Search",
        "args": "{\"term\": \"Save this search\"}"
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
input SaveSearchInput required

Return Parameters

Type Description
SavedSearchResult The created Saved Search object
mutation updateSavedSearch($id: ID!, $input:SavedSearchInput!) {
  updateSavedSearch(id: $id, input: $input) {
    savedSearch {
      id
      label
    }
    errors {
      key
      message
    }
  }
}

{
  "id": "26",
  "input": {
    "label": "This is a updated saved search",
  }
}```

> The above query returns JSON structured like this:

```json
{
  "data": {
    "updateSavedSearch": {
      "errors": null,
      "savedSearch": {
        "id": "26",
        "label": "This is a updated saved search",
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required
input SavedSearchInput required

Return Parameters

Type Description
SavedSearchResult The updated saved search object

Delete a SavedSearch

mutation deleteSavedSearch($id: ID!) {
  deleteSavedSearch(id: $id) {
    errors {
      key
      message
    }
  }
}

{
  "id": "26"
}

The above query returns JSON structured like this:

{
  "data": {
    "deleteSavedSearch": {
      "errors": null,
      "savedSearch": null
    }
  }
}

In case of errors, all the above functions return an error object like the below

{
  "data": {
    "deleteSavedSearch": {
      "errors": [
        {
          "key": "Elixir.Glific.Searches.SavedSearch 26",
          "message": "Resource not found"
        }
      ]
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required

Return Parameters

Parameter Type Default Description
SavedSearchResult An error object or empty

Saved Search Objects

SavedSearch

Field Argument Type Description
id ID
label String
shortcode String
args Json
count Integer This is a computed field, and requires a few DB queries. Use with caution

SavedSearchResult

Field Argument Type Description
errors [InputError]
SavedSearch SavedSearch

SavedSearch Inputs

SavedSearchFilter

Filtering options for savedSearches

Field Type Description
label String Match the label
shortcode String Match the shortcode
isReserved Boolean Match the isReserved status

SavedSearchInput

Field Type Description
label String
shortcode String
Args Json

Messages

Get All Messages

query messages($filter: MessageFilter, $opts: Opts) {
  messages(filter: $filter, opts:$opts) {
    id
    body
    type
    sender {
        id,
        name
    }
  }
}

{
  "opts": {
    "order": "ASC",
    "limit": 10,
    "offset": 0
  },
  "filter": {
    "body": "Hello"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "messages": [
      {
        "id": "3",
        "body": "Hello, how are you",
        "sender": {
          "id": "2",
          "name": "Default Sender"
        }
      },
      {
        "id": "15",
        "body": "Hello world",
        "sender": {
          "id": "13",
          "name": "Althea Hirthe"
        }
      }
    ]
  }
}

This returns all the messages for the organization filtered by the input MessageFilter

Query Parameters

Parameter Type Default Description
filter MessageFilter nil filter the list
opts Opts nil limit / offset / sort order options

Get a specific Message by ID

query message($id: ID!) {
  message(id: $id) {
    message {
      id
      body
      receiver {
        id
        name
      }
    }
  }
}

{
  "id": 2
}

The above query returns JSON structured like this:

{
  "data": {
    "message": {
      "message": {
        "id": "2",
        "body": "Can one desire too much of a good thing?.",
        "receiver": {
          "id": "10",
          "name": "Chrissy Cron"
        }
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
ID ID

Count all Messages

query countMessages($filter: MessageFilter) {
  countMessages(filter: $filter)
}

{
  "filter": {
    "body": "hello"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "countMessage": 2
  }
}

Query Parameters

Parameter Type Default Description
filter MessageFilter nil filter the list

Create a Message

mutation createMessage($input:MessageInput!) {
  createMessage(input: $input) {
    message {
      id
      body
      sender {
        id
        name
      }
    }
    errors {
      key
      message
    }
  }
}

{
  "input": {
    "body": "So wise so young, they say, do never live long.",
    "type": "TEXT"
    "flow": "TEXT"
    "senderId": 1,
    "receiverId": 3
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "createMessage": {
      "errors": null,
      "message": {
        "id": "26",
        "body": "So wise so young, they say, do never live long.",
        "sender": {
          "id": "1",
          "name": "Adelle Cavin"
        }
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
input MessageInput required

Return Parameters

Type Description
MessageResult The created message object

Update a Message

mutation updateMessage($id: ID!, $input:MessageInput!) {
  updateMessage(id: $id, input: $input) {
    message {
      id
      body
      sender {
        id
        name
      }
    }
    errors {
      key
      message
    }
  }
}

{
  "id": "26",
  "input": {
    "body": "It is the east, and Juliet is the sun."
  }
}```

> The above query returns JSON structured like this:

```json
{
  "data": {
    "updateMessage": {
      "errors": null,
      "message": {
        "id": "26",
        "body": "It is the east, and Juliet is the sun.",
        "sender": {
          "id": "3",
          "label": "Conrad Barton"
        }
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required
input MessageInput required

Return Parameters

Type Description
MessageResult The updated message object

Delete a Message

mutation deleteMessage($id: ID!) {
  deleteMessage(id: $id) {
    errors {
      key
      message
    }
  }
}

{
  "id": "26"
}

The above query returns JSON structured like this:

{
  "data": {
    "deleteMessage": {
      "errors": null
    }
  }
}

In case of errors, all the above functions return an error object like the below

{
  "data": {
    "deleteMessage": {
      "errors": [
        {
          "key": "Elixir.Glific.Messages.Message 26",
          "message": "Resource not found"
        }
      ]
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required

Return Parameters

Parameter Type Default Description
MessageResult An error object or empty

Delete a Messages of a contact

mutation clearMessages($contactId: ID!) {
  clearMessages(contactId: $contactId) {
    success
    errors {
      key
      message
    }
  }
}

{
  "contactId": "26"
}

The above query returns JSON structured like this:

{
  "data": {
    "clearMessages": {
      "errors": null,
      "success": true
    }
  }
}

In case of errors, all the above functions return an error object like the below

{
  "data": {
    "clearMessages": {
      "errors": [
        {
          "key": "Elixir.Glific.Contacts.Contact",
          "message": "Resource not found"
        }
      ],
      "success": null
    }
  }
}

Query Parameters

Parameter Type Default Description
contactId ID! required

Return Parameters

Parameter Type Default Description
ClearMessagesResult An error object or empty

Create and send Message

mutation createAndSendMessage($input: MessageInput!) {
  createAndSendMessage(input: $input) {
    message {
      id
      body
      receiver {
        id
        name
      }
    }
    errors {
      key
      message
    }
  }
}

{
  "input": {
    "body": "Test message",
    "flow": "OUTBOUND",
    "type": "TEXT",
    "senderId": 1,
    "receiverId": 2
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "createAndSendMessage": {
      "errors": null,
      "message": {
        "body": "Test message",
        "id": "26",
        "receiver": {
          "id": "2",
          "name": "Default receiver"
        }
      }
    }
  }
}

Create and send SessionTemplate

mutation createAndSendMessage($input: MessageInput!) {
  createAndSendMessage(input: $input) {
    message {
      id
      body
      receiver {
        id
        name
      }
    }
    errors {
      key
      message
    }
  }
}
{
  "input": {
    "flow": "OUTBOUND",
    "type": "TEXT",
    "senderId": 1,
    "receiverId": 11,
    "isHsm": true,
    "params": ["Fifty", "Next Week"],
    "templateId": 32

  }
}

The above query returns JSON structured like this:

{
  "data": {
    "createAndSendMessage": {
      "__typename": "MessageResult",
      "errors": null,
      "message": {
        "__typename": "Message",
        "body": "Your Fifty points will expire on Next Week.",
        "id": "241",
        "isHsm": true,
        "params": null,
        "receiver": {
          "__typename": "Contact",
          "id": "11",
          "name": "Test"
        },
        "templateId": null
      }
    }
  }
}

Create and send Scheduled Message

mutation createAndSendMessage($input: MessageInput!) {
  createAndSendMessage(input: $input) {
    message {
      id
      body
      insertedAt
      sendAt
    }
    errors {
      key
      message
    }
  }
}

{
  "input": {
    "body": "This message should reach at 21:00 (India)",
    "flow": "OUTBOUND",
    "receiverId": 7,
    "sendAt": "2020-07-10T03:30:00Z",
    "senderId": 1,
    "type": "TEXT"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "createAndSendMessage": {
      "errors": null,
      "message": {
        "body": "This message should reach at 21:00 (India)",
        "id": "33",
        "insertedAt": "2020-07-10T13:50:40Z",
        "sendAt": "2020-07-10T15:30:00Z"
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
input MessageInput required

Return Parameters

Parameter Type Default Description
MessageResult An error object or empty

Create and send Session Message to contacts of a collection

mutation createAndSendMessageToGroup($input: MessageInput!, $groupId: ID!) {
  createAndSendMessageToGroup(input: $input, groupId: $groupId) {
    success
    contactIds
    errors {
      key
      message
    }
  }
}

{
  "input": {
    "body": "Test message",
    "flow": "OUTBOUND",
    "type": "TEXT",
    "senderId": 1
  },
  "groupId": 1
}

The above query returns JSON structured like this:

{
  "data": {
    "createAndSendMessageToGroup": {
      "contactIds": ["8"],
      "errors": null,
      "success": true
    }
  }
}

Query Parameters

Parameter Type Default Description
input MessageInput required
groupId [ID]! required

Return Parameters

Parameter Type Default Description
[GroupMessageResult] List of contact ids

Send HSM Message

mutation sendHsmMessage($templateId: ID!, $receiverId: ID!, $parameters: [String]) {
  sendHsmMessage(templateId: $templateId, receiverId: $receiverId, parameters: $parameters) {
    message{
      id
      body
      isHsm
    }
    errors {
      key
      message
    }
  }
}

{
  "templateId": 34,
  "receiverId": 5,
  "parameters": [
    "100",
    "30 Oct"
  ]
}

The above query returns JSON structured like this:

{
  "data": {
    "sendHsmMessage": {
      "errors": null,
      "message": {
        "body": "Your 100 points will expire on 30 Oct.",
        "id": "18",
        "isHsm": true
      }
    }
  }
}

In case of error, above function returns an error object like the below

{
  "data": {
    "sendHsmMessage": null
  },
  "errors": [
    {
      "locations": [
        {
          "column": 3,
          "line": 2
        }
      ],
      "message": "You need to provide correct number of parameters for hsm template",
      "path": ["sendHsmMessage"]
    }
  ]
}

Query Parameters

Parameter Type Default Description
templateId ID! required
receiverId ID! required
parameters [String]! required

Return Parameters

Parameter Type Default Description
MessageResult An error object or empty

Send HSM Message to contacts of a collection

mutation sendHsmMessageToGroup($templateId: ID!, $groupId: ID!, $parameters: [String]) {
  sendHsmMessage(templateId: $templateId, groupId: $groupId, parameters: $parameters) {
    success
    contactIds
    errors {
      key
      message
    }
  }
}

{
  "templateId": 34,
  "groupId": 5,
  "parameters": [
    "100",
    "30 Oct"
  ]
}

The above query returns JSON structured like this:

{
  "data": {
    "sendHsmMessageToGroup": {
      "errors": null,
      "contactIds": ["8"],
      "success": true
    }
  }
}

Query Parameters

Parameter Type Default Description
templateId ID! required
groupId ID! required
parameters [List of String]! required

Return Parameters

Parameter Type Default Description
[GroupMessageResult] List of contact ids

Send Media HSM Message

mutation createAndSendMessage($templateId: ID!, $mediaId: ID!, $receiverId: ID!, $parameters: [String]) {
  createAndSendMessage(templateId: $templateId, mediaId: $mediaId, receiverId: $receiverId, parameters: $parameters) {
    message{
      id
      body
      isHsm
    }
    errors {
      key
      message
    }
  }
}

{
  "templateId": 34,
  "mediaId": 3,
  "receiverId": 5,
  "parameters": [
    "100",
    "30 Oct"
  ]
}

The above query returns JSON structured like this:

{
  "data": {
    "createAndSendMessage": {
      "errors": null,
      "message": {
        "body": "Your 100 points will expire on 30 Oct.",
        "id": "18",
        "isHsm": true
      }
    }
  }
}

In case of error, above function returns an error object like the below

{
  "data": {
    "createAndSendMessage": null
  },
  "errors": [
    {
      "locations": [
        {
          "column": 3,
          "line": 2
        }
      ],
      "message": "You need to provide correct number of parameters for hsm template",
      "path": ["createAndSendMessage"]
    }
  ]
}

Query Parameters

Parameter Type Default Description
templateId ID! required
receiverId ID! required
mediaId ID! required
parameters [String]! required

Return Parameters

Parameter Type Default Description
MessageResult An error object or empty

Subscription for Sent Message

subscription {
  sentMessage() {
    id
    body
    flow
    type
    receiver {
        id
        phone
    }

    sender {
        id
        phone
    }
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "sentMessage": {
      "body": "Test",
      "flow": "OUTBOUND",
      "id": "10397",
      "type": "TEXT",
      "receiver": {
        "id": "484",
        "phone": "91997612324"
      },
      "sender": {
        "id": "1",
        "phone": "917834811114"
      }
    }
  }
}

Return Parameters

Parameter Type Default Description
MessageResult An error or object

Subscription for Update Message Status

subscription {
  update_message_status() {
    id
    body
    flow
    type
    status
    receiver {
        id
        phone
    }

    sender {
        id
        phone
    }
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "update_message_status": {
      "body": "Test",
      "flow": "OUTBOUND",
      "id": "10397",
      "type": "TEXT",
      "status": "sent",
      "receiver": {
        "id": "484",
        "phone": "91997612324"
      },
      "sender": {
        "id": "1",
        "phone": "917834811114"
      }
    }
  }
}

Return Parameters

Parameter Type Default Description
MessageResult An error or object

Subscription for Sent Group Message

subscription {
  sent_group_message() {
    id
    body
    flow
    type
    status
    group_id
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "sent_group_message": {
      "body": "Test",
      "flow": "OUTBOUND",
      "id": "10397",
      "type": "TEXT",
      "status": "sent",
      "group_id": "3"
    }
  }
}

Subscription for Cleared Message

subscription {
  cleared_messages() {
    id
    phone
    name
    lastMessageAt
    optinTime
    bspStatus
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "cleared_messages": {
      "bspStatus": "HSM",
      "id": "100",
      "lastMessageAt": null,
      "name": "contact name",
      "optinTime": "2020-11-25T16:12:18Z",
      "phone": "917834811119"
    }
  }
}

Return Parameters

Parameter Type Default Description
ContactResult An error or object

Subscription for Received Message

subscription {
  receivedMessage() {
    id
    body
    flow
    type
    receiver {
        id
        phone
    }

    sender {
        id
        phone
    }
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "sentMessage": {
      "body": "New Message",
      "flow": "OUTBOUND",
      "id": "10397",
      "type": "TEXT",
      "receiver": {
        "id": "1",
        "phone": "917834811114"
      },
      "sender": {
        "id": "3",
        "phone": "91998782231"
      }
    }
  }
}

Return Parameters

Parameter Type Default Description
MessageResult An error or an object

Remove unread status from messages belonging to a contact

mutation markContactMessagesAsRead($contactId : Gid!) {
  markContactMessagesAsRead(contactId: $contactId)
}

{
  "contactId": "26"
}

The above query returns the same contactID back

{
  "data": {
    "markContactMessagesAsRead": ["26"]
  }
}

Query Parameters

Parameter Type Default Description
contactId Gid! required

Return Parameters

Parameter Type Default Description
Contact ID The same contact ID or an error object

Message Objects

Message

Field Argument Type Description
id ID
body String
type MessageTypesEnum
flow MessageFlowEnum
BspMessageId [String]
SendBy [String]
BspStatus MessageStatusEnum
status MessageStatusEnum
errors Json
Sender Contact
Receiver Contact
Media MessageMedia
ContextMessage Message Context message that the user responded to
isHsm Boolean
isRead Boolean Applicable only to inbound messages
isReplied Boolean For inbound messages, false == Not replied, For outbound messages, false == Not Responded
insertedAt DateTime
updatedAt DateTime
sendAt DateTime
Tags Tags
user User

MessageResult

Field Argument Type Description
errors [InputError]
message Message

GroupMessageResult

Field Argument Type Description
errors [InputError]
success Boolean
contactIds [Id]

ClearMessagesResult

Field Argument Type Description
errors [InputError]
success Boolean

Message Inputs

MessageFilter

Filtering options for messages

Field Type Description
body String Match the body
Sender String Match the sender name
Sender String Match the sender name
Receiver String Match the receiver name
Either String Match the phone with either the sender or receiver
Either String Match the phone with either the sender or receiver
BspStatus MessageStatusEnum Match the status
TagsIncluded [Gid] Match the tags included
TagsExcluded [Gid] Match the tags excluded

MessageInput

Field Type Description
body String
type String
flow MessageFlowEnum
sender_id Id
template_id Id
interactive_template_id Id
receiver_id Id
media_id Id
send_at DateTime

Message Media

Get all message media

query messagesMedia($opts: Opts) {
  messagesMedia(filter: $filter, opts:$opts) {
    id
    url
  }
}

{
  "opts": {
    "order": "ASC",
    "limit": 10,
    "offset": 0
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "messagesMedia": [
      {
        "id": "3",
        "url": "http://robohash.org/set_set3/bgset_bg1/U0E0G",
      },
      {
        "id": "4",
        "url": "http://robohash.org/set_set1/bgset_bg1/dhac5",
      },
    ]
  }
}

This returns all the messages media for the organization.

Query Parameters

Parameter Type Default Description
opts Opts nil limit / offset / sort order options

Get a specific Message Media by ID

query messageMedia($id: ID!) {
  messageMedia(id: $id) {
    messageMedia {
      id
      url
    }
  }
}

{
  "id": 2
}

The above query returns JSON structured like this:

{
  "data": {
    "messageMedia": {
      "messageMedia": {
        "id": "2",
        "url": "http://robohash.org/set_set3/bgset_bg1/ClrvA"
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
ID ID

Count all Message Media

query countMessagesMedia {
  countMessagesMedia
}

The above query returns JSON structured like this:

{
  "data": {
    "countMessagesMedia": 100
  }
}

Validate a Media URL and type

query validateMedia($url: String!, $type: String!) {
  validateMedia(url: $url, type: $type)
}

The above query returns JSON structured like this:

{
  "data": {
    "validateMedia": "{\"is_valid\": true, \"message\": \"success\"}"
  }
}

OR

{
  "data": {
    "validateMedia": "{\"is_valid\": false, \"message\": \"Media content-type is not valid\"}"
  }
}

Create a Message Media

mutation createMessageMedia($input:MessageMediaInput!) {
  createMessageMedia(input: $input) {
    messageMedia {
      id
      url
    }
    errors {
      key
      message
    }
  }
}

{
  "input": {
    "url": "http://robohash.org/set_set3/bgset_bg1/ClrvA",
    "source_url": "http://robohash.org/set_set3/bgset_bg1/ClrvA"
    "caption": "This is a caption"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "messageMedia": {
      "errors": null,
      "messageMedia": {
        "id": "26",
        "url": "http://robohash.org/set_set3/bgset_bg1/ClrvA"
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
input MessageMediaInput required

Return Parameters

Type Description
MessageMediaResult The created message media object

Update a Message Media

mutation updateMessageMedia($id: ID!, $input:MessageMediaInput!) {
  updateMessageMedia(id: $id, input: $input) {
    messageMedia {
      id
      url
      caption
    }
    errors {
      key
      message
    }
  }
}

{
  "id": "26",
  "input": {
    "url": "http://robohash.org/set_set1/bgset_bg1/b7FBMrsOQbn8EJ",
    "caption": "This is a caption"
  }
}```

> The above query returns JSON structured like this:

```json
{
  "data": {
    "updateMessageMedia": {
      "errors": null,
      "messageMedia": {
        "id": "26",
        "url": "http://robohash.org/set_set1/bgset_bg1/b7FBMrsOQbn8EJ",
        "caption": "This is a caption"
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required
input MessageMediaInput required

Return Parameters

Type Description
MessageMediaResult The updated message media object

Delete a Message Media

mutation deleteMessageMedia($id: ID!) {
  deleteMessageMedia(id: $id) {
    errors {
      key
      message
    }
  }
}

{
  "id": "26"
}

The above query returns JSON structured like this:

{
  "data": {
    "deleteMessageMedia": {
      "errors": null
    }
  }
}

In case of errors, all the above functions return an error object like the below

{
  "data": {
    "deleteMessageMedia": {
      "errors": [
        {
          "key": "Elixir.Glific.Messages.MessageMedia 26",
          "message": "Resource not found"
        }
      ]
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required

Return Parameters

Parameter Type Default Description
MessageMediaResult An error object or empty

Message Media Objects

MessageMedia

Field Argument Type Description
id ID
url String
source_url String
thumbnail String
caption String
providerMediaId String

MessageMediaResult

Field Argument Type Description
errors [InputError]
MessageMedia MessageMedia

Message Media Inputs

MessageMediaInput

Field Type Description
url String
source_url String
thumbnail String
caption String

Media Management

Start of the documentation and functionality to incorporate media management into Glific. Note that this will start off as a simple trivial layer over google cloud storage.

Base functionality will be to upload the files to a GCS public bucket, get the url from GCS, to return to client (frontend). Client can then use this url, in a media message to send to WhatsApp user

Upload a file

mutation uploadMedia($media: Upload!, $extension: String!) {
  uploadMedia(media: $media, extension: $extension)
}

The above query returns JSON structured like this:

{
  "data": {
    "uploadMedia":"https://storage.googleapis.com/BUCKET/uploads/outbound/2021-17/NGO Main Account/70253d8b-e419-425f-ad24-7878eb8eb687.png"
   }
}

Upload a buffer

The media blob has to be encoded in base64

mutation uploadBlob($media: String!, $extension: String!) {
  uploadBlob(media: $media, extension: $extension)
}

{
  "input": {
    "media": "W29iamVjdCBCbG9iXQ==",
    "extension": "wav"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "uploadBlob":"https://storage.googleapis.com/BUCKET/uploads/outbound/2021-17/NGO Main Account/70253d8b-e419-425f-ad24-7878eb8eb687.png"
   }
}

BlobInput

Field Argument Type Description
media [String]
extension String

Session Template

Get All Session Templates

query sessionTemplates($filter: SessionTemplateFilter, $opts: Opts) {
  sessionTemplates(filter: $filter, opts:$opts) {
    id
    body
    label
    shortcode
    isHsm
    type
    isActive
    translation
    isReserved
    isSource
    parent {
      id
      label
    }
    language {
      id
      label
    }
    messageMedia {
      id
      caption
    }
  }
}

{
  "filter": {
    "body": "template",
    "term": "label"
  },
  "opts": {
    "order": "ASC",
    "limit": 10,
    "offset": 0
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "sessionTemplates": [
      {
        "body": "Another Template",
        "id": "2",
        "isActive": false,
        "isHsm": false,
        "isReserved": false,
        "isSource": false,
        "label": "Another Template Label",
        "language": {
          "id": "2",
          "label": "English"
        },
        "messageMedia": null,
        "parent": {
          "id": "1",
          "label": "Default Template Label"
        },
        "shortcode": null,
        "translations": "{\"2\":{\"number_parameters\":0,\"language_id\":2,\"body\":\"एक और टेम्पलेट\"}}",
        "type": "TEXT"
      },
      {
        "body": "Default Template",
        "id": "1",
        "isActive": false,
        "isHsm": false,
        "isReserved": false,
        "isSource": false,
        "label": "Default Template Label",
        "language": {
          "id": "2",
          "label": "English"
        },
        "messageMedia": null,
        "parent": null,
        "shortcode": null,
        "translations": "{\"2\":{\"number_parameters\":0,\"language_id\":2,\"body\":\"पूर्व उपस्थित नमूना\"}}",
        "type": "TEXT"
      }
    ]
  }
}

This returns all the session templates filtered by the input SessionTemplateFilter

Query Parameters

Parameter Type Default Description
filter SessionTemplateFilter nil filter the list
opts Opts nil limit / offset / sort order options

Return Parameters

Type Description
[SessionTemplate] List of session templates

Get a specific SessionTemplate by ID

query sessionTemplate($id: ID!) {
  sessionTemplate(id: $id) {
    sessionTemplate {
      id
      body
      label
      shortcode
      translation
      type
      language {
        id
        label
      }
    }
  }
}

{
  "id": 1
}

The above query returns JSON structured like this:

{
  "data": {
    "sessionTemplate": {
      "sessionTemplate": {
        "body": "Default Template",
        "id": "1",
        "label": "Default Template Label",
        "language": {
          "id": "2",
          "label": "English"
        },
        "shortcode": null,
        "translations": "{\"2\":{\"number_parameters\":0,\"language_id\":2,\"body\":\"पूर्व उपस्थित नमूना\"}}",
        "type": "TEXT"
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
filter SessionTemplateFilter nil filter the list

Return Parameters

Type Description
SessionTemplateResult Queried SessionTemplate

Count all Session Templates

query countSessionTemplates($filter: SessionTemplateFilter) {
  countSessionTemplates(filter: $filter)
}

{
  "filter":  {
    "language": "Hindi"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "countSessionTemplates": 15
  }
}

Query Parameters

Parameter Type Default Description
filter SessionTemplateFilter nil filter the list

Return Parameters

Type Description
Int Count of filtered session templates

Get List of Whatsapp HSM categories

query {
  whatsappHsmCategories
}

The above query returns JSON structured like this:

{
  "data": {
    "whatsappHsmCategories": [
      "ACCOUNT_UPDATE",
      "PAYMENT_UPDATE",
      "PERSONAL_FINANCE_UPDATE",
      "SHIPPING_UPDATE",
      "RESERVATION_UPDATE",
      "ISSUE_RESOLUTION",
      "APPOINTMENT_UPDATE",
      "TRANSPORTATION_UPDATE",
      "TICKET_UPDATE",
      "ALERT_UPDATE",
      "AUTO_REPLY"
    ]
  }
}

This returns list of whatsapp HSM categories

Return Parameters

Type Description
[String] List of categories

Create a Session Template

mutation createSessionTemplate($input:SessionTemplateInput!) {
  createSessionTemplate(input: $input) {
    sessionTemplate {
      id
      body
      label
      shortcode
      type
    }
    errors{
            key
      message
    }
  }
}

{
  "input": {
    "body": "Test template",
    "label": "Test label",
    "languageId": 1,
    "translations": "{\"2\":{\"number_parameters\":0,\"language_id\":2,\"body\":\"पूर्व उपस्थित नमूना\"}}"
    "type": "TEXT"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "createSessionTemplate": {
      "errors": null,
      "sessionTemplate": {
        "body": "Test template",
        "id": "34",
        "label": "Test label",
        "shortcode": null,
        "translations": "{\"2\":{\"number_parameters\":0,\"language_id\":2,\"body\":\"पूर्व उपस्थित नमूना\"}}",
        "type": "TEXT"
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
input SessionTemplateInput required

Return Parameters

Type Description
SessionTemplateResult The created session template object

Import Session Templates

mutation RootMutationType($data: String!, $importTemplatesId: ID!) {
  importTemplates(data: $data, id: $importTemplatesId) {
    errors {
      key
      message
    }
    status
  }
}

{
  "data": "Template Id,Template Name,Body,Type,Quality Rating,Language,Status,Created On\r\n6122571,2meq_payment_link,  Your OTP for {{1}} is {{2}}. This is valid for {{3}}.,TEXT,Unknown,English,APPROVED,2021-07-16\n6122572,meq_payment_link2,You are one step away! Please click the link below to make your payment for the Future Perfect program.,TEXT,Unknown,English,Rejected,2021-07-16"
}

The above query returns JSON structured like this:

{
  "data": {
    "importTemplates": {
      "errors": null,
      "success": false
    }
  }
}

Query Parameters

Parameter Type Default Description
input Data required

Return Parameters

Type Description
importTemplatesResult The imported templates success status

Update a SessionTemplate

mutation updateSessionTemplate($id: ID!, $input:SessionTemplateInput!) {
  updateSessionTemplate(id: $id, input: $input) {
    sessionTemplate {
      id
      body
      label
      shortcode
      translation
      type
    }
    errors {
      key
      message
    }
  }
}

{
  "id": "1",
  "input": {
    "body": "Test template"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "updateSessionTemplate": {
      "errors": null,
      "sessionTemplate": {
        "body": "Test template",
        "id": "1",
        "label": "Default Template Label",
        "shortcode": null,
        "translations": "{\"2\":{\"number_parameters\":0,\"language_id\":2,\"body\":\"पूर्व उपस्थित नमूना\"}}",
        "type": "TEXT"
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required
input SessionTemplateInput required

Return Parameters

Type Description
SessionTemplateResult The updated session template object

Delete a SessionTemplate

mutation deleteSessionTemplate($id: ID!) {
  deleteSessionTemplate(id: $id) {
    errors {
      key
      message
    }
  }
}

{
  "id": "3"
}

The above query returns JSON structured like this:

{
  "data": {
    "deleteSessionTemplate": {
      "errors": null
    }
  }
}

In case of errors, all the above functions return an error object like the below

{
  "data": {
    "deleteSessionTemplate": {
      "errors": [
        {
          "key": "Elixir.Glific.Templates.SessionTemplate 3",
          "message": "Resource not found"
        }
      ]
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required

Return Parameters

Type Description
SessionTemplateResult An error object or empty

Session Template Objects

SessionTemplate

Field Argument Type Description
body String
id ID
isActive Boolean
isReserved Boolean
isSource Boolean
label String
language Language
messageMedia MessageMedia
parent SessionTemplate
shortcode String
type MessageTypesEnum
isHsm Boolean
status String
number_parameters Int
category String
example String
insertedAt DateTime
translations Json
updatedAt DateTime

SessionTemplateResult

Field Argument Type Description
errors [InputError]
sessionTemplate SessionTemplate

Session Template Inputs

SessionTemplateFilter

Filtering options for session_templates

Field Type Description
term String Match term with labe/body/shortcode of template or label/shortcode of associated tag
body String Match the body of template
isActive Boolean Match the active flag
isReserved Boolean Match the reserved flag
label String Match the label
language String Match a language
languageId Int Match a language id
parent String Match the parent
parentId Int Match the parent
shortcode String Match the translations
translations Json Match the shortcode of template
is_hsm Boolean Match the hsm template message
status String Match the whatsapp status of hsm template message

SessionTemplateInput

Field Type Description
body String
isActive Boolean
isSource Boolean
isHsm Boolean
category String
example String
translations Json
label String
languageId ID
shortcode String
type MessageTypesEnum
HasButtons Boolean
buttonType TemplateButtonTypeEnum
buttons Json

Groups

Get All Groups

query groups($filter: GroupFilter, $opts: Opts) {
  groups(filter: $filter, opts:$opts) {
    id
    label
    isRestricted
    contactsCount
    usersCount
  }
}

{
  "opts": {
    "order": "ASC",
    "limit": 10,
    "offset": 0
  },
  "filter": {
    "label": "Group"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "groups": [
      {
        "contactsCount": 2,
        "id": "1",
        "isRestricted": false,
        "label": "Default Group",
        "usersCount": 2
      },
      {
        "contactsCount": 1,
        "id": "2",
        "isRestricted": true,
        "label": "Restricted Group",
        "usersCount": 1
      }
    ]
  }
}

This returns all the groups for the organization

Query Parameters

Parameter Type Default Description
filter GroupFilter nil filter the list
opts Opts nil limit / offset / sort order options

Get All Organization Groups

query organization_groups($filter: GroupFilter, $opts: Opts, $id: Id) {
  organization_groups(filter: $filter, opts: $opts, id:$id) {
    id
    label
    isRestricted
    contactsCount
    usersCount
  }
}

{
  "opts": {
    "order": "ASC",
    "limit": 10,
    "offset": 0
  },
  "filter": {
    "label": "Group"
  },
  "id": "1"
}

The above query returns JSON structured like this:

{
  "data": {
    "groups": [
      {
        "contactsCount": 2,
        "id": "1",
        "isRestricted": false,
        "label": "Default Group",
        "usersCount": 2
      },
      {
        "contactsCount": 1,
        "id": "2",
        "isRestricted": true,
        "label": "Restricted Group",
        "usersCount": 1
      }
    ]
  }
}

This returns all the groups for the organization

Query Parameters

Parameter Type Default Description
filter GroupFilter nil filter the list
opts Opts nil limit / offset / sort order options
id ID nil organization id

Get a Group by ID

query group($id: ID!) {
  group(id: $id) {
    group {
      id
      label
      isRestricted
      contacts{
        name
      }
      users{
        name
      }
    }
  }
}

{
    "id": 1
}

The above query returns JSON structured like this:

{
  "data": {
    "group": {
      "group": {
        "contacts": [
          {
            "name": "Glific Admin"
          },
          {
            "name": "Adelle Cavin"
          }
        ],
        "id": "1",
        "isRestricted": false,
        "label": "Default Group",
        "users": [
          {
            "name": "Glific Admin"
          }
        ]
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID nil

Get Group Information for a Group by ID

Returns a count of the total number of contacts in the group, along with a breakdown of each type: "none", "session", "session_and_hsm", "hsm". If a key is missing, the value is 0

  query groupInfo($id: ID!) {
    groupInfo(id: $id)
}

{
  "id": "2"
}

The above query returns JSON structured like this:

{
  "data": {
    "groupInfo": "{\"total\":2,\"session_and_hsm\":1,\"session\":1}"
  }
}

Query Parameters

Parameter Type Default Description
id ID nil

Create Group

mutation createGroup($input: GroupInput!) {
  createGroup(input: $input) {
    group {
      id
      label
    }
    errors {
      key
      message
    }
  }
}
{
  "input": {
    "label": "My First Group"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "createGroup": {
      "group": {
        "id": "1",
        "label": "My First Group"
      }
    }
  }
}

{
  "data": {
    "createGroup": {
      "errors": [
        {
          "key": "label",
          "message": "has already been taken"
        }
      ],
      "group": null
    }
  }
}

Query Parameters

Parameter Type Default Description
input GroupInput required

Return Parameters

Type Description
GroupResult The created group object

Update a Group

mutation updateGroup($id: ID!, $input: GroupInput!) {
  updateGroup(id: $id, input: $input) {
    group {
      id
      label
      isRestricted
    }
    errors {
      key
      message
    }
  }
}

{
  "id": 2,
    "input": {
    "label": "My First Updated non-Restricted Group",
    "isRestricted": false
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "updateGroup": {
      "errors": null,
      "group": {
        "id": "2",
        "isRestricted": false,
        "label": "My First Updated non-Restricted Group"
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID required
input GroupInput required

Return Parameters

Type Description
GroupResult The updated group object

Delete a Group

mutation deleteGroup($id: ID!) {
  deleteGroup(id: $id) {
    errors {
      key
      message
    }
  }
}

{
  "id": 2
}

The above query returns JSON structured like this:

{
  "data": {
    "deleteGroup": {
      "errors": null
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID required

Return Parameters

Type Description
GroupResult An error object or empty

Group Objects

Field Argument Type Description
id ID
isRestricted Boolean
label String
description String
contacts [Contact]
users [User]
messages [Message]
contactsCount Integer
usersCount Integer
lastCommunicationAt DateTime

GroupResult

Field Argument Type Description
errors [InputError]
group Group

Group Inputs

GroupInput

Field Type Description
isRestricted Boolean
label String
description String

Contact Group

Join table between contacts and groups

Create Contact Group

mutation createContactGroup($input: ContactGroupInput!) {
  createContactGroup(input: $input) {
    contactGroup {
      id
      contact {
        id
        name
      }
      group {
        id
        label
      }
    }
    errors {
      key
      message
    }
  }
}

{
  "input": {
    "contactId": 2,
    "groupId": 1
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "createContactGroup": {
      "contactGroup": {
        "contact": {
          "id": "2",
          "name": "Default receiver"
        },
        "group": {
          "id": "1",
          "label": "My First Group"
        },
        "id": "1"
      },
      "errors": null
    }
  }
}

Query Parameters

Parameter Type Default Description
input ContactGroupInput required

Return Parameters

Type Description
ContactGroupResult The created contact group object

Update a Group with contacts to be added and contacts to be deleted

mutation updateGroupContacts($input: GroupContactsInput!) {
  updateGroupContacts(input: $input) {
    groupContacts {
      id
      group {
        label
      }
      contact {
        name
      }
    }
    numberDeleted
  }
}

{
  "input": {
    "groupId": 2,
    "addContactIds": [1, 2],
    "deleteContactIds": [3, 8]
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "updateGroupContacts": {
      "groupContacts": [
        {
          "contact": {
            "name": "Default Receiver"
          },
          "group": {
            "label": "Art"
          },
          "id": "2"
        },
        {
          "contact": {
            "name": "Glific Admin"
          },
          "group": {
            "label": "Art"
          },
          "id": "1"
        }
      ],
      "numberDeleted": 1
    }
  }
}

Query Parameters

Parameter Type Default Description
input GroupContactsInput required

Return Parameters

Type Description
groupContacts The list of contact groups added
integer The number of contact groups deleted

Update groups to be added and groups to be deleted to a Contact

mutation updateContactGroups($input: ContactGroupsInput!) {
  updateContactGroups(input: $input) {
    contactGroups {
      id
      group {
        label
      }
      contact {
        name
      }
    }
    numberDeleted
  }
}

{
  "input": {
    "contactId": 2,
    "addGroupIds": [1],
    "deleteGroupIds": [2, 3]
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "updateContactGroups": {
      "numberDeleted": 2,
      "contactGroups": [
        {
          "group": {
            "label": "Poetry"
          },
          "id": "13",
          "contact": {
            "name": "Default Receiver"
          }
        }
      ]
    }
  }
}

Query Parameters

Parameter Type Default Description
input ContactGroupsInput required

Return Parameters

Type Description
contactGroups The list of contact groups added
integer The number of contact groups deleted

ContactGroup Objects

ContactGroup

Field Argument Type Description
contact Contact
group Group
id ID
value String

ContactGroupResult

Field Argument Type Description
contactGroup ContactGroup
errors [InputError]

ContactGroup Inputs

ContactGroupInput

Field Type Description
contactId ID
groupId ID

GroupContactsInput

Field Type Description
GroupId Id
AddContactIds [Id]
DeleteContactIds [Id]

ContactGroupsInput

Field Type Description
ContactId Id
AddGroupIds [Id]
DeleteGroupIds [Id]

Message Group

Join table between messages and groups

Create Message Group

mutation createMessageGroup($input: MessageGroupInput!) {
  createMessageGroup(input: $input) {
    messageGroup {
      id
      message {
        id
        name
      }
      group {
        id
        label
      }
    }
    errors {
      key
      message
    }
  }
}

{
  "input": {
    "messageId": 2,
    "groupId": 1
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "createMessageGroup": {
      "messageGroup": {
        "message": {
          "id": "2",
          "name": "Default receiver"
        },
        "group": {
          "id": "1",
          "label": "My First Group"
        },
        "id": "1"
      },
      "errors": null
    }
  }
}

Query Parameters

Parameter Type Default Description
input MessageGroupInput required

Return Parameters

Type Description
MessageGroupResult The created message group object

Delete a MessageGroup

mutation deleteMessageGroup($id: ID!) {
  deleteMessageGroup(id: $id) {
    errors {
      key
      message
    }
  }
}

{
  "id": 1
}

The above query returns JSON structured like this:

{
  "data": {
    "deleteMessageGroup": {
      "errors": null
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID required

Return Parameters

Type Description
MessageGroupResult An error object or empty

MessageGroup Objects

MessageGroup

Field Argument Type Description
message Message
group Group
id ID
value String

MessageGroupResult

Field Argument Type Description
messageGroup MessageGroup
errors [InputError]

MessageGroup Inputs

MessageGroupInput

Field Type Description
messageId ID
groupId ID

User Group

Join table between users and groups

Create User Group

mutation createUserGroup($input: UserGroupInput!) {
  createUserGroup(input: $input) {
    userGroup {
      id
      user {
        id
        name
      }
      group {
        id
        label
      }
    }
    errors {
      key
      message
    }
  }
}

{
  "input": {
    "userId": 2,
    "groupId": 1
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "createUserGroup": {
      "errors": null,
      "userGroup": {
        "group": {
          "id": "1",
          "label": "Test Group"
        },
        "id": "5",
        "user": {
          "id": "1",
          "name": "John Doe"
        }
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
input UserGroupInput required

Return Parameters

Type Description
UserGroupResult The created user group object

Update a Group with users to be added and users to be deleted

mutation updateGroupUsers($input: GroupUsersInput!) {
  updateGroupUsers(input: $input) {
    groupUsers {
      id
      group {
        label
      }
      user {
        name
      }
    }
    numberDeleted
  }
}

{
  "input": {
    "groupId": 2,
    "addUserIds": [1, 2],
    "deleteUserIds": [3, 8]
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "updateGroupUsers": {
      "groupUsers": [
        {
          "group": {
            "label": "Art"
          },
          "id": "10",
          "user": {
            "name": "NGO Basic User 1"
          }
        },
        {
          "group": {
            "label": "Art"
          },
          "id": "9",
          "user": {
            "name": "Glific Admin"
          }
        }
      ],
      "numberDeleted": 2
    }
  }
}

Query Parameters

Parameter Type Default Description
input GroupUsersInput required

Return Parameters

Type Description
groupUsers The list of user groups added
integer The number of user groups deleted

Update groups to be added and groups to be deleted to a User

mutation updateUserGroups($input: UserGroupsInput!) {
  updateUserGroups(input: $input) {
    userGroups {
      id
      group {
        label
      }
      user {
        name
      }
    }
    numberDeleted
  }
}

{
  "input": {
    "userId": 2,
    "addGroupIds": [1],
    "deleteGroupIds": [2, 3]
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "updateUserGroups": {
      "numberDeleted": 2,
      "userGroups": [
        {
          "group": {
            "label": "Poetry"
          },
          "id": "13",
          "user": {
            "name": "NGO Basic User 1"
          }
        }
      ]
    }
  }
}

Query Parameters

Parameter Type Default Description
input UserGroupsInput required

Return Parameters

Type Description
userGroups The list of user groups added
integer The number of user groups deleted

UserGroup Objects

UserGroup

Field Argument Type Description
group Group
id ID
user User
value String

UserGroupResult

Field Argument Type Description
errors [InputError]
userGroup UserGroup

UserGroup Inputs

UserGroupInput

Field Type Description
groupId ID
userId ID

GroupUsersInput

Field Type Description
GroupId Id
AddUserIds [Id]
DeleteUserIds [Id]

UserGroupsInput

Field Type Description
UserId Id
AddGroupIds [Id]
DeleteGroupIds [Id]

Flows

Get All Flows

query flows($filter: FlowFilter, $opts: Opts) {
  flows(filter: $filter, opts: $opts) {
    id
    uuid
    name
    versionNumber
    flowType
    keywords
    lastPublishedAt
    lastChangedAt
  }
}

{
  "opts": {
    "limit": 2,
    "offset": 0,
    "order": "ASC"
  },
  "filter": {
    "name": "Workflow"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "flows": [
      {
        "flowType": "MESSAGE",
        "id": "1",
        "keywords": ["help", "मदद"],
        "name": "Help Workflow",
        "uuid": "3fa22108-f464-41e5-81d9-d8a298854429",
        "lastChangedAt": "2021-03-25T10:03:26Z",
        "lastPublishedAt": "2021-03-25T10:03:26Z",
        "versionNumber": "13.1.0"
      },
      {
        "flowType": "MESSAGE",
        "id": "2",
        "keywords": ["language"],
        "name": "Language Workflow",
        "uuid": "f5f0c89e-d5f6-4610-babf-ca0f12cbfcbf",
        "lastChangedAt": "2021-03-25T10:03:26Z",
        "lastPublishedAt": "2021-03-25T10:03:26Z",
        "versionNumber": "13.1.0"
      }
    ]
  }
}

This returns all the flows

Query Parameters

Parameter Type Default Description
filter FlowFilter nil filter the list
opts Opts nil limit / offset / sort order options

Return Parameters

Type Description
[Flow] List of flows

Get a specific Flow by ID

query flow($id: ID!) {
  flow(id: $id) {
    flow {
      id
      name
    }
  }
}

{
  "id": 1
}

The above query returns JSON structured like this:

{
  "data": {
    "flow": {
      "flow": {
        "id": "1",
        "name": "Help Workflow"
      }
    }
  }
}

Return Parameters

Type Description
FlowResult Queried Flow

Count all Flows

query countFlows($filter: FlowFilter) {
  countFlows(filter: $filter)
}

{
  "filter": {
    "name": "help"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "countFlows": 2
  }
}

Create a Flow

mutation ($input: FlowInput!) {
  createFlow(input: $input) {
    flow {
      id
      name
      keywords
      isActive
    }
    errors {
      key
      message
    }
  }
}

{
  "input": {
    "keywords": [
      "tests",
      "testing"
    ],
    "name": "test workflow",
    "isActive": true
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "createFlow": {
      "errors": null,
      "flow": {
        "id": "12",
        "keywords": ["tests", "testing"],
        "name": "test workflow"
      }
    }
  }
}

In case of errors, above functions return an error object like the below

{
  "data": {
    "createFlow": {
      "errors": [
        {
          "key": "name",
          "message": "can't be blank"
        }
      ],
      "flow": null
    }
  }
}

Query Parameters

Parameter Type Default Description
input FlowInput required

Return Parameters

Type Description
FlowResult The created flow object

Update a Flow

mutation updateFlow($id: ID!, $input:FlowInput!) {
  updateFlow(id: $id, input: $input) {
    flow {
      id
      name
      keywords
    }
    errors {
      key
      message
    }
  }
}

{
  "id": "1",
  "input": {
    "name": "updated name",
    "keywords": ["test", "testing"]
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "updateFlow": {
      "errors": null,
      "flow": {
        "id": "1",
        "name": "updated name",
        "keywords": ["test", "testing"]
      }
    }
  }
}

In case of errors, above functions return an error object like the below

{
  "data": {
    "updateFlow": {
      "errors": [
        {
          "key": "keywords",
          "message": "global keywords [test, testing] are already taken"
        }
      ],
      "flow": null
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required
input FlowInput required

Return Parameters

Type Description
FlowResult The updated flow object

Delete a Flow

mutation deleteFlow($id: ID!) {
  deleteFlow(id: $id) {
    flow {
      id
      name
    }
    errors {
      key
      message
    }
  }
}

{
  "id": "3"
}

The above query returns JSON structured like this:

{
  "data": {
    "deleteFlow": {
      "errors": null,
      "flow": null
    }
  }
}

In case of errors, all the above functions return an error object like the below

{
  "data": {
    "deleteFlow": {
      "errors": [
        {
          "key": "Elixir.Glific.Flows.Flow 3",
          "message": "Resource not found"
        }
      ],
      "flow": null
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required

Return Parameters

Type Description
FlowResult An error object or empty

Publish a Flow

mutation publishFlow($uuid: UUID4!) {
  publishFlow(uuid: $uuid) {
    success
    errors {
      key
      message
    }
  }
}

{
  "uuid": "3fa22108-f464-41e5-81d9-d8a298854429"
}

The above query returns JSON structured like this:

{
  "data": {
    "publishFlow": {
      "errors": null,
      "success": true
    }
  }
}

In case of errors, all the above functions return an error object like the below

{
  "data": {
    "publishFlow": {
      "errors": [
        {
          "key": "Flow UUID: 9a2788e1-26cd-44d0-8868-d8f0552a08a6",
          "message": "Resource not found"
        }
      ],
      "success": null
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required

Return Parameters

Type Description
FlowResult An error object or response true

Start flow for a contact

mutation startContactFlow($flowId: ID!, $contactId: ID!) {
  startContactFlow(flowId: $flowId, contactId: $contactId) {
    success
    errors {
        key
        message
    }
  }
}

{
  "flowId": "1",
  "contactId": "2"
}

The above query returns JSON structured like this:

{
  "data": {
    "startContactFlow": {
      "errors": null,
      "success": true
    }
  }
}

In case of errors, all the above functions return an error object like the below

{
  "data": {
    "startContactFlow": {
      "errors": [
        {
          "key": "contact",
          "message": "Cannot send the message to the contact."
        }
      ],
      "success": null
    }
  }
}

Query Parameters

Parameter Type Default Description
flowId ID! required
contactId ID! required

Return Parameters

Type Description
FlowResult An error object or success response true

Resume flow for a contact

mutation resumeContactFlow($flowId: ID!, $contactId: ID!, $result: JSON!) {
  resumeContactFlow(flowId: $flowId, contactId: $contactId, result: $result) {
    success
    errors {
        key
        message
    }
  }
}

{
  "flowId": "1",
  "contactId": "2"
  "result": {"one": 1, "two": 2, "three": 3}
}

The above query returns JSON structured like this:

{
  "data": {
    "startContactFlow": {
      "errors": null,
      "success": true
    }
  }
}

In case of errors, all the above functions return an error object like the below

{
  "data": {
    "startContactFlow": {
      "errors": [
        {
          "key": "contact",
          "message": "does not have any active flows awaiting results."
        }
      ],
      "success": null
    }
  }
}

Query Parameters

Parameter Type Default Description
flowId ID! required
contactId ID! required
result JSON! required

Return Parameters

Type Description
FlowResult An error object or success response true

Start flow for a group contacts

mutation startGroupFlow($flowId: ID!, $groupId: ID!) {
  startGroupFlow(flowId: $flowId, groupId: $groupId) {
    success
    errors {
        key
        message
    }
  }
}

{
  "flowId": "1",
  "groupId": "1"
}

The above query returns JSON structured like this:

{
  "data": {
    "startGroupFlow": {
      "errors": null,
      "success": true
    }
  }
}

In case of errors, all the above functions return an error object like the below

{
  "data": {
    "startGroupFlow": {
      "errors": [
        {
          "key": "Elixir.Glific.Flows.Flow 11",
          "message": "Resource not found"
        }
      ],
      "success": null
    }
  }
}

Query Parameters

Parameter Type Default Description
flowId ID! required
groupId ID! required

Return Parameters

Type Description
FlowResult An error object or success response true

Copy a Flow

mutation copyFlow($id: ID!, $input:FlowInput!) {
  copyFlow(id: $id, input: $input) {
    flow {
      id
      name
      keywords
    }
    errors {
      key
      message
    }
  }
}

{
  "id": "1",
  "input": {
    "name": "new name"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "copyFlow": {
      "errors": null,
      "flow": {
        "id": "32",
        "keywords": [],
        "name": "new name"
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required
input FlowInput required

Return Parameters

Type Description
FlowResult The copied flow object

Import a Flow

mutation ($flow: JSON!) {
  importFlow(flow: $flow){
    success
    errors {
      key
      message
    }
  }
}

{
  "input": {
    "{\"flows\":[{\"keywords\":[\"hello\"],\"definition\":{\"vars\":[\"a941004f-adc8-43f2-b819-68eec8d1e912\"],\"uuid\":\"a941004f-adc8-43f2-b819-68eec8d1e912\",\"type\":\"messaging\",\"spec_version\":\"13.1.0\",\"revision\":1,\"nodes\":[{\"uuid\":\"59c67035-59ab-47fa-a1fd-a50978aa78c5\",\"exits\":[{\"uuid\":\"49d2775d-a658-4c74-be10-b7d605b4ea6f\",\"destination_uuid\":null}],\"actions\":[{\"uuid\":\"4d4dc0f1-9056-4bf1-a58e-df26b861088e\",\"type\":\"send_msg\",\"text\":\"hehlo\",\"quick_replies\":[],\"attachments\":[]}]}],\"name\":\"hello\",\"localization\":{},\"language\":\"base\",\"expire_after_minutes\":10080,\"_ui\":{\"nodes\":{\"59c67035-59ab-47fa-a1fd-a50978aa78c5\":{\"type\":\"execute_actions\",\"position\":{\"top\":0,\"left\":0}}}}}}],\"contact_field\":[],\"collections\":[]}"
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "importFlow": {
      "errors": null,
      "success": false
    }
  }
}

Query Parameters

Parameter Type Default Description
input Json required

Return Parameters

Type Description
FlowResult The imported flow success status

Export a Flow

mutation exportFlow($id: ID!) {
  publishFlow(id: $id) {
    export_data
    errors {
      key
      message
    }
  }
}

{
  "id": 10
}

The above query returns JSON structured like this:

{
  "data": {
    "exportFlow": {
      "export_data": "{\"flows\":[{\"vars\":[\"3fa22108-f464-41e5-81d9-d8a298854429\"],\"uuid\":\"3fa22108-f464-41e5-81d9-d8a298854429\",\"type\":\"message\",\"spec_version\":\"13.1.0\",\"nodes\":[{\"uuid\":\"3ea030e9-41c4-4c6c-8880-68bc2828d67b\",\"exits\":[{\"uuid\":\"a8311645-482e-4d35-b300-c92a9b18798b\",\"destination_uuid\":\"6f68083e-2340-449e-9fca-ac57c6835876\"}],\"actions\":[{\"uuid\":\"e319cd39-f764-4680-9199-4cb7da647166\",\"type\":\"send_msg\",\"text\":\"Thank you for reaching out. This is your help message along with some options-\\n      \\n*Type 1* for option 1\\n*Type 2* for option 2\\n*Type 3* for option 3\\n*Type 4* to optout and stop receiving our messages\",\"quick_replies\":[],\"attachments\":[]}]},{\"uuid\":\"6f68083e-2340-449e-9fca-ac57c6835876\",\"router\":{\"wait\":{\"type\":\"msg\"},\"type\":\"switch\",\"operand\":\"@input.text\",\"default_category_uuid\":\"65da0a4d-2bcc-42a2-99f5-4c9ed147f8a6\",\"categories\":[{\"uuid\":\"de13e275-a05f-41bf-afd8-73e9ed32f3bf\",\"name\":\"One\",\"exit_uuid\":\"744b1082-4d95-40d0-839a-89fc1bb99d30\"},{\"uuid\":\"d3f0bf85-dac1-4b7d-8084-5c1ad2575f12\",\"name\":\"Two\",\"exit_uuid\":\"77cd0e42-6a13-4122-a5fc-84b2e2daa1d4\"},{\"uuid\":\"243766e5-e353-4d65-b87a-4405dbc24b1d\",\"name\":\"Three\",\"exit_uuid\":\"0caba4c7-0955-41c9-b8dc-6c58112503a0\"},{\"uuid\":\"3ce58365-61f2-4a6c-9b03-1eeccf988952\",\"name\":\"Four\",\"exit_uuid\":\"1da8bf0a-827f-43d8-8222-a3c79bcace46\"},{\"uuid\":\"65da0a4d-2bcc-42a2-99f5-4c9ed147f8a6\",\"name\":\"Other\",\"exit_uuid\":\"d11aaf4b-106f-4646-a15d-d18f3a534e38\"}],\"cases\":[{\"uuid\":\"0345357f-dbfa-4946-9249-5828b58161a0\",\"type\":\"has_any_word\",\"category_uuid\":\"de13e275-a05f-41bf-afd8-73e9ed32f3bf\",\"arguments\":[\"1\"]},{\"uuid\":\"bc425dbf-d50c-48cf-81ba-622c06e153b0\",\"type\":\"has_any_word\",\"category_uuid\":\"d3f0bf85-dac1-4b7d-8084-5c1ad2575f12\",\"arguments\":[\"2\"]},{\"uuid\":\"be6bc73d-6108-405c-9f88-c317c05311ad\",\"type\":\"has_any_word\",\"category_uuid\":\"243766e5-e353-4d65-b87a-4405dbc24b1d\",\"arguments\":[\"3\"]},{\"uuid\":\"ebacc52f-a9b0-406d-837e-9e5ca1557d17\",\"type\":\"has_any_word\",\"category_uuid\":\"3ce58365-61f2-4a6c-9b03-1eeccf988952\",\"arguments\":[\"4\"]}]},\"exits\":[{\"uuid\":\"744b1082-4d95-40d0-839a-89fc1bb99d30\",\"destination_uuid\":\"f189f142-6d39-40fa-bf11-95578daeceea\"},{\"uuid\":\"77cd0e42-6a13-4122-a5fc-84b2e2daa1d4\",\"destination_uuid\":\"85e897d2-49e4-42b7-8574-8dc2aee97121\"},{\"uuid\":\"0caba4c7-0955-41c9-b8dc-6c58112503a0\",\"destination_uuid\":\"6d39df59-4572-4f4c-99b7-f667ea112e03\"},{\"uuid\":\"1da8bf0a-827f-43d8-8222-a3c79bcace46\",\"destination_uuid\":\"a5105a7c-0917-4900-a0ce-cb5d3be2ffc5\"},{\"uuid\":\"d11aaf4b-106f-4646-a15d-d18f3a534e38\",\"destination_uuid\":\"3ea030e9-41c4-4c6c-8880-68bc2828d67b\"}],\"actions\":[]},{\"uuid\":\"f189f142-6d39-40fa-bf11-95578daeceea\",\"exits\":[{\"uuid\":\"d002db23-a51f-4183-81d6-b1e93c5132fb\",\"destination_uuid\":\"ca4e201c-b500-418e-8fdf-97ac0d4a80a5\"}],\"actions\":[{\"uuid\":\"ed7d10f7-6298-4d84-a8d2-7b1f6e91da07\",\"type\":\"send_msg\",\"text\":\"Message for option 1\",\"quick_replies\":[],\"attachments\":[]}]},{\"uuid\":\"6d39df59-4572-4f4c-99b7-f667ea112e03\",\"exits\":[{\"uuid\":\"b913ee73-87d2-495b-8a2d-6e7c40f31fd5\",\"destination_uuid\":\"ca4e201c-b500-418e-8fdf-97ac0d4a80a5\"}],\"actions\":[{\"uuid\":\"10196f43-87f0-4205-aabd-1549aaa7e242\",\"type\":\"send_msg\",\"text\":\"Message for option 3\",\"quick_replies\":[],\"attachments\":[]}]},{\"uuid\":\"a5105a7c-0917-4900-a0ce-cb5d3be2ffc5\",\"exits\":[{\"uuid\":\"df45c811-b1fe-4d25-a925-88f8d7ad6fc9\",\"destination_uuid\":null}],\"actions\":[{\"uuid\":\"36051723-7d00-422e-8846-2336a9ecbc9d\",\"type\":\"send_msg\",\"text\":\"Message for option 4\",\"quick_replies\":[],\"attachments\":[],\"all_urns\":false},{\"value\":\"optout\",\"uuid\":\"690c3e48-d31a-4819-86a6-e6dc11aa8ff8\",\"type\":\"set_contact_field\",\"field\":{\"name\":\"Settings\",\"key\":\"settings\"}}]},{\"uuid\":\"85e897d2-49e4-42b7-8574-8dc2aee97121\",\"exits\":[{\"uuid\":\"37a545df-825b-4611-a7fe-b17dfb62c430\",\"destination_uuid\":\"ca4e201c-b500-418e-8fdf-97ac0d4a80a5\"}],\"actions\":[{\"uuid\":\"a970d5d9-2951-48dc-8c66-ee6833c4b21e\",\"type\":\"send_msg\",\"text\":\"Message for option 2. You can add them to a group based on their response.\",\"quick_replies\":[],\"attachments\":[\"image:https://www.buildquickbots.com/whatsapp/media/sample/jpg/sample01.jpg\"]}]},{\"uuid\":\"ca4e201c-b500-418e-8fdf-97ac0d4a80a5\",\"exits\":[{\"uuid\":" <> ...
    }
  }
} ,
    }
  }
}

Query Parameters

Parameter Type Default Description
id ID! required

Return Parameters

Type Description
ExportFlowResults An error object or response true

Get a flow

Gets a flow for the logged in user.

query flowGet($id: ID!) {
  flowGet(id: $id) {
    id
    name
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "flowGet": {
      "id": "2",
      "name": "Activity"
    }
  }
}

OR if no flow is available

{
  "data": {
    "flowGet": null
  }
}

Query Parameters

Parameter Type Default Description

Return Parameters

Type Description
Flow A flow object

Release a flow contact

Releases a flow for the logged in user if one exists. The system also releases the flow when it has been idle for more than 10 minutes and there is a request for a flow

query flowRelease {
  flowRelease {
    id
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "flowRelease": null
  }
}

Query Parameters

Parameter Type Default Description

Return Parameters

Type Description

Flow Objects

Flow

Field Argument Type Description
flowType String
id ID
name String
uuid UUID4
versionNumber String
keywords [String]
status [String]
ignoreKeywords Boolean
isActive Boolean
isBackground Boolean
insertedAt DateTime
updatedAt DateTime
lastPublishedAt DateTime
lastChangedAt DateTime

FlowResult

Field Argument Type Description
errors [InputError]
flow Flow

Flow Inputs

FlowInput

Field Type Description
name String
keywords [String]
ignoreKeywords Boolean
isActive Boolean
isBackground Boolean

FlowFilter

Filtering options for flows

Field Type Description
name String Match the flow name
nameOrKeyword String Match the flow name and keywords
keyword String Match the flow keyword
uuid UUID4
isActive Boolean Match the isActive flag of flow
isBackground Boolean Match the isBackground flag of flow
status String Match the status of flow revision draft/archived/published

Terminate flows for a contact

Terminate all active flows for a contact.

mutation terminateContactFlows($contactId: ID!) {
  terminateContactFlows(contactId: $contactId) {
    errors {
      key
      value
    }
    success
  }
}

The above query returns JSON structured like this:

{
  "success": true,
  "errors": null
}

Query Parameters

Parameter Type Default Description
ID ID nil Contact ID

Return Parameters

Field Type Description
errors [InputError]
success Boolean

Reset flow counts for a specific flow

Reset all counts for a flow

mutation resetFlowCount($flowId: ID!) {
  resetFlowCount(flowId: $flowId) {
    errors {
      key
      value
    }
    success
  }
}

The above query returns JSON structured like this:

{
  "success": true,
  "errors": null
}

Query Parameters

Parameter Type Default Description
ID ID nil Flow ID

Return Parameters

Field Type Description
errors [InputError]
success Boolean

Glific Contact Import

Import Contacts API

mutation importContacts($group_label : String, $data : String) {
  importContacts(group_label: $group_label, data: $data) {
      status

      errors {
      key
      message
    }
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "importContacts": {
      "status": "All contacts added"
    }
  }
}

Query Parameters

Parameter Type Default Description
group_label String required The contacts are added to the group with this label
data String required The csv data as string.
id Id required organization to which contacts needed to be uploaded.
type ImportContactEnum required Type of data for importing contacts.

function import_contacts(organization_id, group_label, opts \ [])

The import_contacts method can be used for performing bulk add/update/deletion of provider contacts in the database.

CSVFormat

The function operates on csv style formatted data. The CSV data needs to be of the following format: (check the shell tab on right)

name,phone,Language,opt_in,delete
test,9989329297,english,2021-03-09
test2,1111111111,hindi,2021-03-09,1

The method supports extracting this CSV data from three mechanisms:

The method operates on the following logic:

The method takes in the following parameters:

Examples

You will need to fun these examples from iex

iex> Glific.Contacts.Import.import_contacts(1, "Group", file_path: "test.csv")
iex> `Glific.Contacts.Import.import_contacts(1,"Group", url: "http://foo.com/bar.csv")
iex> Glific.Contacts.Import.import_contacts(1,"Group", data: "name,phone,Language,opt_in,delete\ntest2,1111111111,hindi,2021-03-09,1")
iex> Glific.Contacts.Import.import_contacts(1, "Group", file_path: "test.csv", date_format: "{YYYY}-{M}-{D}")

SaaS

Start of the documentation and functionality to run Glific as your very own SaaS. In keeping with our open source philosophy, everything we do will be open, to encourage more SaaS providers to offer Glific locally

Billing with stripe is already included as part of the core platform, and hence will not be covered in this section. As we make advances in that area, we will add more documentation

Create an organization, organization contact and BSP credentials

One function to rule them all. Grab the minimum amount of information that we require from the user to bootstrap their account. All the other functionality can be done via the main Glific interface

At this stage, this is open to the world. However the organization created is marked as not active AND not approved, so they really cannot login. In the next version, we will add simple OTP based authentication to ensure the Admin is opted in with the SaaS WhatsApp Business API Account.

If you are using axios or other libraries, send the following in the BODY of a POST request

{
  "name": "Sample Organization",
  "shortcode": "sample",
  "phone": "WhatsApp Business API Registered number",
  "api_key": "Gupshup API Key",
  "app_name": "Gupshup App Name",
  "email": "Email Address of Admin",
}

The above query returns JSON structured like this:

In the case of a validation failure

{
  "is_valid": FALSE,
  "messages": {email: "email is invalid", shortcode: "shortcode already taken"}
}

Or in the case of success

{
  "is_valid": TRUE,
  "messages": [],
  "organization": "Organization Object",
  "contact": "Contact Object",
  "credential": "Message indicating creating a credential was successful"
}

Update Organization Status IsActive or IsApproved

mutation updateOrganizationStatus($updateOrganizationid: ID!, $isActive: Boolean, $isApproved: Boolean) {
  updateOrganizationStatus($updateOrganizationid: updateOrganizationid, $isActive: isActive, $isApproved: isApproved) {}
    organization {
      email
      isActive
      isApproved
      name
      shortcode
    }
    errors {
      key
      message
    }
  }
}

{
  "isActive": true,
  "isApproved": true,
  "updateOrganizationId": 1,
}

The above query returns JSON structured like this:

{
  "data": {
    "updateOrganizationStatus": {
      "errors": null,
      "organization": {
        "__typename": "Organization",
        "email": "ADMIN@gmail.com",
        "isActive": true,
        "isApproved": true,
        "name": "Glific",
        "shortcode": "glific"
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
updateOrganizationId ID! required
isActive Boolean required
isApproved Boolean required

Return Parameters

Type Description
OrganizationResult The updated organization object

Delete Organization with status as inactive

mutation deleteInactiveOrganization($deleteOrganizationID: ID!, $isConfirmed: Boolean) {}
  deleteInactiveOrganization(
    deleteOrganizationID: $deleteOrganizationID,
    isConfirmed: $isConfirmed) {
    organization {
      email
      isActive
      isApproved
      name
      shortcode
    }
    errors {
      key
      message
    }
  }
}

{
  "id": "1",
  "input": {
    "isConfirmed": true,
    "deleteOrganizationId": 1,
  }
}

The above query returns JSON structured like this:

{
  "data": {
    "deleteInactiveOrganization": {
      "errors": null,
      "organization": {
        "__typename": "Organization",
        "email": "ADMIN@gmail.com",
        "isActive": true,
        "isApproved": true,
        "name": "Glific",
        "shortcode": "glific"
      }
    }
  }
}

Query Parameters

Parameter Type Default Description
deleteOrganizationID ID! required
isConfirmed Boolean required

Return Parameters

Type Description
OrganizationResult The updated organization object

Reset selected tables from Organization

Used to delete potential test and sample data. Currently only deletes entries from * Messages * Flow Results * Flow Context * Resets Contact Fields and Settings to empty

mutation resetOrganization($resetOrganizationID: ID!, $isConfirmed: Boolean) {}
  resetOrganization(
    resetOrganizationID: $resetOrganizationID,
    isConfirmed: $isConfirmed)
}

{
  "reset_organization_id": "2",
  "isConfirmed": true
}

The above query returns JSON structured like this:

{
  "data": {
    "resetOrganization": {
      "Successfully reset tables and fields of organization"
    }
  }
}

Query Parameters

Parameter Type Default Description
resetOrganizationID ID!! required
isConfirmed Boolean required

Return Parameters

Type Description
Status Message Message indicating successful completion

OrganizationStatusInput

Field Type Description
updateOrganizationId ID Unique
isActive Boolean
isApproved Boolean

Glific System

Objects

InputError

An error encountered trying to persist input

Field Argument Type Description
key String!
message String!

Inputs

Opts

Lets collapse sort order, limit and offset into its own little groups

Field Type Description
limit Int
offset Int
order SortOrder
order_with String The field in the DB to sort the results with. Applies to simple objects only.

Scalars

Boolean

The Boolean scalar type represents true or false.

DateTime

The DateTime scalar type represents a date and time in the UTC timezone. The DateTime appears in a JSON response as an ISO8601 formatted string, including UTC timezone ("Z"). The parsed date and time string will be converted to UTC if there is an offset.

Time

The Time scalar type represents a time without microseconds precision. The Time appears in a JSON response as an ISO8601 formatted string.

Gid

The gid scalar appears in JSON as a String. The string appears to the glific backend as an integer

ID

The ID scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as "4") or integer (such as 4) input value will be accepted as an ID.

Int

The Int scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^53 - 1) and 2^53 - 1 since it is represented in JSON as double-precision floating point numbers specified by IEEE 754.

Json

A generic json type so return the results as json object

String

The String scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.

UUID4

The UUID4 scalar type represents UUID4 compliant string data, represented as UTF-8 character sequences. The UUID4 type is most often used to represent unique human-readable ID strings.

Enums

ContactStatusEnum

The Contact Status enum

Value Description
FAILED
INVALID
PROCESSING
VALID
BLOCKED

ContactProviderStatusEnum

The Contact BSP Provider Status enum

Value Description
NONE
SESSION
SESSION_AND_HSM
HSM

MessageFlowEnum

The Message Flow enum

Value Description
INBOUND
OUTBOUND

MessageStatusEnum

The Message Status enum

Value Description
DELIVERED
ENQUEUED
ERROR
READ
RECEIVED
SENT
CONTACT OPT OUT

MessageTypesEnum

The Message Types enum

Value Description
AUDIO
CONTACT
DOCUMENT
HSM
IMAGE
LOCATION
TEXT
VIDEO
STICKER

SortOrder

Enum for ordering results

Value Description
ASC
DESC

Errors

The Glific API uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Your API key is wrong.
403 Forbidden -- The glific requested is hidden for administrators only.
404 Not Found -- The specified glific could not be found.
429 Too Many Requests -- You're requesting too many glifics! Slow down!
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.