Mutations define GraphQL operations which change data on the server. They are the primary way to take actions with your data in Kana. The majority of operations below require you to provide the fields you want returned after the mutation occurs - the same principles that apply to Queries apply here too.

At the start of every mutation operation, ensure that you specify mutation before the field(s).

Query Variables

We use variables throughout our example requests. We do this in order to mirror real-world application practices whereby you would most likely want dynamic values for your arguments. Take a look at this guide if you’re unfamiliar with how variables work in GraphQL.

createFeature

Create a Feature.

Arguments

NameTypeDescription
inputCreateFeatureInput!The input needed to create the feature. See Inputs for more.

Return Fields

NameTypeDescription
dataFeature!The Feature which was created.
errors / errorSee ErrorsReturns any errors which may have occurred with the request.

Examples

Request Body

mutation createFeature($input: CreateFeatureInput!) {
  createFeature(input: $input) {
    id
    name
    type
    unitLabel
    unitLabelPlural
    metadata
  }
}

Request Query Variables

{
  "input": {
    "id": "api-calls",
    "name": "API Calls",
    "type": "CONSUMABLE",
    "unitLabel": "API Call",
    "unitLabelPlural": "API Calls",
    "metadata": {}
  }
}

Response JSON

{
  "data": {
    "createFeature": {
      "id": "api-calls",
      "name": "API Calls",
      "type": "CONSUMABLE",
      "unitLabel": "API Call",
      "unitLabelPlural": "API Calls",
      "metadata": {}
    }
  }
}

updateFeature

Update a Feature.

Arguments

NameTypeDescription
inputUpdateFeatureInput!The input needed to update the feature. See Inputs for more.

Return Fields

NameTypeDescription
dataFeature!The Feature which was updated.
errors / errorSee ErrorsReturns any errors which may have occurred with the request.

Examples

Request Body

mutation updateFeature($input: UpdateFeatureInput!) {
  updateFeature(input: $input) {
    id
    name
    type
    unitLabel
    unitLabelPlural
    metadata
    packages {
      id
      name
      status
      isAddon
      updatedAt
      features {
        id
        name
        type
        limit
        unitLabel
        unitLabelPlural
        metadata
      }
      prices {
        id
        provider
        amount
        displayAmount
        currency
        interval
      }
    }
  }
}

Request Query Variables

{
  "id": "api-calls",
  "input": {
    "name": "API Calls",
    "unitLabel": "API Call",
    "unitLabelPlural": "API Calls",
    "metadata": {}
  }
}

Response JSON

{
  "data":{
    "updateFeature":{
      "id":"api-calls",
      "name":"API Calls",
      "type":"CONSUMABLE",
      "unitLabel": "API Call",
      "unitLabelPlural": "API Calls",
      "metadata":{},
      "packages":[
        {
          "id":"pro-plan",
          "name":"Pro Plan",
          "status":"PUBLISHED",
          "metadata":{},
          "isAddon":false,
          "updatedAt":"2022-05-10T12:39:08.965Z",
          "features":[
            {
              "id":"api-calls",
              "name":"API Calls",
              "limit":"1000",
              "type":"CONSUMABLE"
              "unitLabel": "API Call",
              "unitLabelPlural": "API Calls",
              "metadata":{}
            }
          ],
          "prices":[
            {
              "id": "price_1L7NHvIiEnRX8aivoxbSWREF",
              "provider": "STRIPE",
              "amount": 5000,
              "displayAmount": "50.00",
              "currency": "gbp",
              "interval": "month"
            }
          ]
        }
      ]
    }
  }
}

createPackage

Create a Package.

Package Status

Your package will always have a status of DRAFT upon being created. If you want to publish this package then you will have to do so through the Dashboard.

Arguments

NameTypeDescription
inputCreatePackageInput!The input needed to create the package. See Inputs for more.

Return Fields

NameTypeDescription
dataPackage!The Package which was created.
errors / errorSee ErrorsReturns any errors which may have occurred with the request.

Examples

Request Body

mutation createPackage($input: CreatePackageInput!) {
  createPackage(input: $input) {
    id
    name
    status
    metadata
    features {
      id
      name
      limit
      type
      unitLabel
      unitLabelPlural
      metadata
    }
    prices {
      id
      provider
      amount
      displayAmount
      currency
      interval
    }
    isAddon
    updatedAt
  }
}

Request Query Variables

{
  "input": {
    "id": "pro-plan",
    "name": "Pro Plan",
    "isAddon": false,
    "metadata": {},
    "features": {
      "id": "api-calls",
      "entitlement": {
        "limit": 1000,
        "resetPeriod": "MONTH",
        "overageEnabled": false
      }
    }
  }
}

Response JSON

{
  "data": {
    "createPackage": {
      "id": "pro-plan",
      "name": "Pro Plan",
      "status": "DRAFT",
      "metadata": {},
      "features": [
        {
          "id": "api-calls",
          "name": "API Calls",
          "limit": "1000",
          "type": "CONSUMABLE",
          "unitLabel": "API Call",
          "unitLabelPlural": "API Calls",
          "metadata": {}
        }
      ],
      "prices": [
        {
          "id": "price_1L7NHvIiEnRX8aivoxbSWREF",
          "provider": "STRIPE",
          "amount": 5000,
          "displayAmount": "50.00",
          "currency": "gbp",
          "interval": "month"
        }
      ],
      "isAddon": false,
      "updatedAt": "2021-11-25T16:57:42.778Z"
    }
  }
}

updatePackage

Update a Package.

Only metadata can be updated on the Package object through the API. All other updates will need to be done through the Dashboard. Let us know if you want to see further updatable fields and your use-cases!

Arguments

NameTypeDescription
inputUpdatePackageInput!The input needed to update the package. See Inputs for more.

Return Fields

NameTypeDescription
dataPackage!The Package which was updated.
errors / errorSee ErrorsReturns any errors which may have occurred with the request.

Examples

Request Body

mutation updatePackage($input: UpdatePackageInput!) {
  updatePackage(input: $input) {
    id
    name
    status
    metadata
    features {
      id
      name
      limit
      type
      unitLabel
      unitLabelPlural
      metadata
    }
    prices {
      id
      provider
      amount
      displayAmount
      currency
      interval
    }
    isAddon
    updatedAt
  }
}

Request Query Variables

{
  "id": "pro-plan",
  "input": {
    "metadata": {}
  }
}

Response JSON

{
  "data": {
    "updatePackage": {
      "id": "pro-plan",
      "name": "Pro Plan",
      "status": "DRAFT",
      "metadata": {},
      "features": [
        {
          "id": "api-calls",
          "name": "API Calls",
          "limit": "1000",
          "type": "CONSUMABLE",
          "unitLabel": "API Call",
          "unitLabelPlural": "API Calls",
          "metadata": {}
        }
      ],
      "prices": [
        {
          "id": "price_1L7NHvIiEnRX8aivoxbSWREF",
          "provider": "STRIPE",
          "amount": 5000,
          "displayAmount": "50.00",
          "currency": "gbp",
          "interval": "month"
        }
      ],
      "isAddon": false,
      "updatedAt": "2021-11-25T16:57:42.778Z"
    }
  }
}

createUser

Create a User.

Arguments

NameTypeDescription
inputCreateUserInput!The input needed to create the user. See Inputs for more.

Return Fields

NameTypeDescription
dataUser!The User which was created.
errors / errorSee ErrorsReturns any errors which may have occurred with the request.

Examples

Request Body

mutation createUser($input: CreateUserInput!) {
  createUser(input: $input) {
    id
    billingId
    name
    email
    metadata
  }
}

Request Query Variables

{
  "input": {
    "id": "124",
    "billingId": "cus_883y74hdjjdjdnd",
    "name": "Test User",
    "email": "test@usekana.com",
    "metadata": {}
  }
}

Response JSON

{
  "data": {
    "createUser": {
      "id": "124",
      "billingId": "cus_883y74hdjjdjdnd",
      "name": "Test User",
      "email": "test@usekana.com",
      "metadata": {}
    }
  }
}

updateUser

Update a User.

How can I update the email or billingId of a user?

You will need to do this through a CSV Import within our Dashboard. We’ll soon make this possible through the API.

Arguments

NameTypeDescription
inputUpdateUserInput!The input needed to update the user. See Inputs for more.

Return Fields

NameTypeDescription
dataUser!The User which was updated.
errors / errorSee ErrorsReturns any errors which may have occurred with the request.

Examples

Request Body

mutation updateUser($id: String!, $input: CreateUserInput!) {
  updateUser(id: $id, input: $input) {
    id
    billingId
    name
    email
    metadata
  }
}

Request Query Variables

{
  "id": "124",
  "input": {
    "id": "125",
    "name": "Updated User",
    "metadata": {}
  }
}

Response JSON

{
  "data": {
    "createUser": {
      "id": "125",
      "billingId": "cus_883y74hdjjdjdnd",
      "name": "Updated User",
      "email": "test@usekana.com",
      "metadata": {}
    }
  }
}

subscribe

Subscribe a User to a Package - either one or multiple. Returns a PackageSubscription.

Users can only be subscribed to a Package with a status of PUBLISHED.

Arguments

NameTypeDescription
packageIds[String!]!An array of id’s for the packages which the user is to be subscribed to. These are the id fields of aPackage.
userIdString!The identifier of the user to subscribe the package(s) to. This maps to the id field as set on the User object.

Return Fields

NameTypeDescription
data[Subscription]!An array of subscriptions to the packages which the user in question has just been subscribed to.
errors / errorSee ErrorsReturns any errors which may have occurred with the request.

Examples

Request Body

mutation subscribeUserToPlan($packageIds: [String!]!, $userId: String!) {
  subscribe(packageIds: $packageIds, userId: $userId) {
    id
    userId
    status
    package {
      id
      name
      status
      metadata
      features {
        id
      	name
        limit
        type
        unitLabel
        unitLabelPlural
        metadata
      }
      prices {
        id
        provider
        amount
        displayAmount
        currency
        interval
      }
      isAddon
      updatedAt
    }
  }
}

Request Query Variables

{
  "packageIds": ["free-trial", "proactive-messaging"],
  "userId": "124"
}

Response JSON

{
  "data": {
    "subscribe": [
      {
        "id": "2",
        "userId": "124",
        "status": "ACTIVE",
        "metadata": {},
        "package": {
          "id": "free-trial",
          "name": "Free Trial",
          "status": "PUBLISHED",
          "metadata": {},
          "features": [
            {
              "id": "api-calls",
              "name": "API Calls",
              "limit": "1000",
              "type": "CONSUMABLE",
              "unitLabel": "API Call",
              "unitLabelPlural": "API Calls",
              "metadata": {}
            }
          ],
          "prices": [
            {
              "id": "price_1L7NHvIiEnRX8aivoxbSWREF",
              "provider": "STRIPE",
              "amount": 5000,
              "displayAmount": "50.00",
              "currency": "gbp",
              "interval": "month"
            }
          ],
          "isAddon": false,
          "updatedAt": "2021-11-25T16:57:42.778Z"
        }
      },
      {
        "id": "3",
        "userId": "124",
        "status": "CANCELLED",
        "package": {
          "id": "proactive-messaging",
          "name": "Proactive Messaging",
          "status": "PUBLISHED",
          "metadata": {},
          "features": [
            {
              "id": "messages",
              "name": "Messages",
              "limit": "50",
              "type": "CONSUMABLE",
              "unitLabel": "Message",
              "unitLabelPlural": "Message",
              "metadata": {}
            }
          ],
          "prices": [
            {
              "id": "price_id_6gSGwU839shamnskk7LSNME",
              "provider": "STRIPE",
              "amount": 2000,
              "displayAmount": "20.00",
              "currency": "gbp",
              "interval": null
            }
          ],
          "isAddon": true,
          "updatedAt": "2021-11-27T18:25:10.081Z"
        }
      }
    ]
  }
}

Errors

recordUsage

Records the usage of a Feature by a User, including the amount it was used by.

Revert Usage

If you want to revert usage by a certain amount (ie. subtract rather than add from the usage of a feature), you can do so by providing a negative amount in the delta argument (ie. -1).

Arguments

NameTypeDescription
inputCreateUsageEventInput!The input needed to record the usage event. See Inputs for more.

Return Fields

NameTypeDescription
dataRecordedUsageAn object containing information on whether the usage of the feature was recorded or not (recorded boolean and reason).
errors / errorSee ErrorsReturns any errors which may have occurred with the request.

Examples

Request Body

mutation recordUsage($input: CreateUsageEventInput!) {
  recordUsage(input: $input) {
    recorded
    reason
  }
}

Request Query Variables

{
  "input": {
    "userId": "124",
    "featureId": "api-calls",
    "delta": 100,
    "action": "SET"
  }
}

Response JSON

{
  "data": {
    "recordUsage": {
      "recorded": true,
      "reason": null
    }
  }
}

Generate a payment link which a user can navigate to in order to pay and subscribe to a Package.

A billing template (which has a price associated to it) must be created and linked to the package you want a user to subscribe to. You can do so in the Dashboard. You will need to provide a valid templateId - otherwise aSubscriptionLinkError error will be returned.

Upon successful payment, we will automatically receive notification of the user and the packages they have subscribed to in order to create PackageSubscriptions. You do not need to notify Kana (ie. through the subscribe mutation) yourself.

Arguments

NameTypeDescription
userIdStringThe identifier of the user who will be subscribing. This maps to the id field as set on the User object. Your billing provider will otherwise create this user in Kana for you if you don’t have an identifier available.
templateIdString!The identifier of the billing template which is related to the package and price which you want to subscribe the user to.
successUrlString!The URL which you want to redirect users to upon successful payment to subscribe.
cancelUrlString!The URL which you want to redirect users to upon a cancelled payment to subscribe.

Returns

NameTypeDescription
dataSubscriptionLink!An object containing the generated URL (url) which a user can navigate to in order to pay and subscribe to a package.
errors / errorSee ErrorsReturns any errors which may have occurred with the request.

Examples

Request Body

mutation generateSubscriptionLink($userId: String, $templateId: String!, $successUrl: String!, $cancelUrl: String!) {
  generateSubscriptionLink(userId: $userId, templateId: $templateId, successUrl: $successUrl, cancelUrl: $cancelUrl) {
    url
  }
}

Request Query Variables

{
  "userId": "124",
  "templateId": "pro-50gbp-month",
  "successUrl": "https://usekana.com/pricing/success",
  "cancelUrl": "https://usekana.com/pricing/cancelled"
}

Response JSON

{
  "data": {
    "generateSubscriptionLink": {
      "url": "https://checkout.stripe.com/pay/cs_test_a1l1XbatH0jyo4PBOr2ZUdzSZYjgTevA6B1feZIloI8Wv0jWLDE6JTsgre#fidkdWxOYHwnPyd1blpxYHZxWjA0TkJsMlJCbWhMT2Y8QjI3bnZVajVsVWtWQzU3Z0BufHdpdEBTb11GdH00V0xNdlFsSXxqVjRGTXFCRlxsXzxSNWw0XWNRQ2ljclBTR1Q8XEBLMXBkV3ZDNTVRRGZAbDZ1cycpJ2N3amhWYHdzNHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYCkndnF3bHVgRGZmanBrcSc%2FL2RmZnFaNE50TXVuTXxWVGowPUF2byd4JSUn"
    }
  }
}

generateUserToken

Generates a user-specific token for the client-side Client SDK (Frontend). You can find out more in our Authorization (Frontend) guide.

Arguments

NameTypeDescription
userIdString!The id of the User who you want to generate the token for.

Return Fields

NameTypeDescription
dataGeneratedUserTokenAn object containing the token which can be used to authenticate a user with the Client SDK.
errors / errorSee ErrorsReturns any errors which may have occurred with the request.

Examples

Request Body

mutation generateUserToken($userId: String!) {
  generateUserToken(userId: $userId)
}

Request Query Variables

{
  "userId": "124"
}

Response JSON

{
  "data": {
    "generateUserToken": {
      "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpLOPTE.eyJhcFAKERI6InRlc3RfZmhqZGlqaHMiLCJ1c2VySWQiOiIxMjQiLCJpYXQiOjE2NTIyNjI4MTUsImV4cCI6MTY1NDg1NDgxNSwiYXVkIjoia2FuYS1jbGllbnQiLCJpc3MiOiJ1c2VrYW5hLmNvbSJ9.hD3NeQlykA7ucCvbLp3bYEHye23zlca85yhq1s2C6a8"
    }
  }
}