The API lives at https://demoapi.machinelabs.com/v1/ . It’s a graphQL API – see https://graphql.org/learn/ for an overview of how that works. Basically you’ll be POSTing a JSON query to the API URL, and getting a JSON response.

You should have been given an API key and your brand ID when you signed up – you’ll need this for all requests.

To get a full list of available queries, mutations, and types, visit https://demoapi.machinelabs.com/v1/ and look at the Docs panel on the right hand side. The documentation below provides general information on how all of these mutations work, which you can combine with the graphQL documentation above to get the signature for any specific query or mutation.

Authentication

Each request you make to the GraphQL endpoint will need to include an X-Machinelabs-Api-Key header with the value set to your API key. Each API keys is specific to a single brand so if you have multiple brands then you will need to store a unique key for each. If you lose your API key or it is compromised then please contact support immediately and we can invalidate it and create a new one for you.

Uploading data

You’ll probably want to upload historical data, such as contacts and orders, and then regularly upload any new data, or update any data that has changed.

The main pieces of data you’ll want to upload to use machine labs are contacts, products, and orders. You might also want to upload custom mailing lists (see ‘Mailing lists’ below for the default ones we provide), checkouts (for checkout abandonment automations), refunds (for reporting), product collections (for segmenting by collection), custom merge fields (for adding extra data to contacts), if you want to use any of those features.

There are graphQL mutations for each type of data, which all work the same way. For example, to upload mailing lists, you’d use this mutation:

mutation uploadMailingLists($mailingLists: [MailingListInput]!) {
    uploadMailingLists(mailingLists: $mailingLists) {
        result {
            yourId
            machineLabsId
        }
        errors {
            message
        }
    }
}

and could use these variables:

{
    "mailingLists": [{
        "yourId": "mailingList1",
        "name": "My mailing list",
        "description": "A mailing list",
    }],
}

The response will look something like this:

{
  "data": {
    "uploadMailingLists": {
      "result": [
        {
          "yourId": "mailingList1",
          "machineLabsId": "fb9acacf85b645d9a679fd5032542406"
        }
      ],
      "errors": null
    }
  }
}

The result key provides the machineLabsId we’ve assigned to each object you uploaded, matched to yourId (the identifier you gave when you uploaded it). You need to store the machineLabsId, as you’ll need it to update the object in future.

To update that object in future (for example here to change the description), include it in an uploadMailingLists call as above, but including the machineLabsId from your initial upload of the object so we know you’re updating an object instead of creating it. You can have a mixture of new and updated objects in a single upload batch.

{
    "mailingLists": [{
        "yourId": "mailingList1",
        "machineLabsId": "the machineLabsId you obtained above",
        "name": "My mailing list",
        "description": "A new description",
    }],
}

Errors

If the data you supplied is in some way invalid, you’ll get a response like:

{
  "data": {
    "uploadMailingLists": {
      "result": null,
      "errors": [
        {
          "message": "The following machineLabsId values aren't recognised, please create these interests with uploadMailingLists - fb9acacf85b645d9a679fd5032542407"
        }
      ]
    }
  }
}

with a message that should explain what needs fixed. No data will be imported for a batch until all errors are fixed.

If we encounter an internal error of some kind, the data will again not be imported, and you’ll get a response like:

{
  "errors": [
    {
      "message": "An error occurred",
    }
  ],
  "data": {
    "uploadMailingLists": null
  }
}

Some data depends on other data. For example, when uploading refunds with uploadRefunds, each refund requires an orderId. You’ll need to first upload the order with uploadOrders, and store the machineLabsId you get back so you can provide it in uploadRefunds.

Some objects include other objects, for example the orders provided to uploadOrders include a list of order_items. If you provide a new list of related objects when you update an object, any existing related objects not included in the list will be deleted. For these, you provide yourId, but you don’t get a machineLabsId – you just update them by reuploading the parent object.

Subscriptions

Once you’ve uploaded contacts, you can use the updateSubscriptions mutation to subscribe them to mailing lists, or unsubscribe them. Use the customMailingListSubscriptions argument to subscribe contacts to any custom mailing lists you’ve uploaded using uploadMailingLists, or newsletterListSubscription and customersListSubscription to manage subscriptions to our two built-in lists.

Note that your subscription changes will only take effect if no errors are returned.

Changes will also only be applied if the lastUpdated value you provide is greater than the last time the relevant subscription was updated in Machine Labs. For example, if you saw a user subscribe to a list in your system at 1pm and push that data at 1:05pm, but they unsubscribed from that same list in Machine Labs at 1:04pm, we’ll treat the data in our system as most up-to-date, and will not make any changes. This will still be treated as a successful update – it won’t return any errors – but no data will be changed at our side, as we’re already up-to-date.

Queries

Keeping up with subscription changes

If you’re maintaining a contact’s subscription status in your system, you’ll need to keep up to date with any changes to their subscription status in our system.

You can fetch a list of subscription changes in a time period using subscriptionUpdates. Upload your contacts, store the date/time the upload completed, then regularly fetch the list of updates since you last checked.

query subscriptionUpdates($changedSince: DateTime!) {
  subscriptionUpdates(changedSince: $changedSince) {
      edges {
          node {
              contactId
              mailingListId
              subscribed
              lastUpdated
              isNewsletterList
              isCustomersList
          }
      }
  }
}

Special mailing lists

Machine Labs has some special built-in mailing lists that will be created automatically. Two have special fields for them on subscriptionUpdates results – isNewsletterList and isCustomersList, to indicate that the subscription is for a given special list, rather than a normal one. Similarly, uploadContacts has special fields on contacts for these subscriptions – newsletterListSubscription and customersListSubscription.

The third built-in mailing list – checkout abandonment – is not accessible via the API, and is managed completely by Machine Labs based on the checkouts you update via uploadCheckouts. Make sure to sync your checkout data with us regularly to keep the checkout abandonment list up to date.