Documentation

General API requirements

This document specifies how to implement an API for your service according to the IFTTT Service Protocol. It is recommended that you treat this document as a reference and follow the workflow outlined in our overview.

HTTPS

The production version of your service API must be served over HTTPS.

API URL prefix

Designate an API URL prefix for all of your API endpoints in your service configuration.

Examples
  • https://api.service.com
  • https://service.com/api
Endpoint paths

Endpoints are scoped to the current version of the IFTTT Service Protocol by appending your API URL prefix with /ifttt/v1 for all requests.

Examples
  • {{api_url_prefix}}/ifttt/v1/triggers/any_new_photo
  • {{api_url_prefix}}/ifttt/v1/actions/post_photo
Headers

Use UTF-8 as the response encoding and support HTTP-level compression. Requests from IFTTT to your service API have the following headers:

Headers
  • 
    Accept:          application/json
    Accept-Charset:  utf-8
    Accept-Encoding: gzip, deflate
    Content-Type:    application/json
    
HTTP status codes

Use the following set of HTTP response status codes:

status Description
200 The request was a success.
400 There was something wrong with incoming data from IFTTT. Provide an error response body to clarify what went wrong.
401 IFTTT sent an OAuth2 access token that isn’t valid.
404 IFTTT is trying to reach a URL that doesn’t exist.
500 There was an error in your application logic.
503 Your service is not available at the moment, but IFTTT should try again later.
Response body format

Provide response bodies as JSON objects. Success responses have a top-level wrapper object called data.

Raw body on success
  • {
      "data": {
        // The value of `data` varies, but is typically
        // either an object or array
        ...
      }
    }
    

Error responses have a top-level errors array. Each element of errors is an object with a message property whose value is a user-friendly error message.

Raw body on error
  • {
      "errors": [
        {
          "message": "Something went wrong!"
        }
      ]
    }
    

Service connection

If your service requires user authentication, users must connect your service before they can use its triggers or actions.

Service connection has two steps:

  1. Authentication flow. This step authorizes IFTTT to make requests to your service API on behalf of the user.
  2. Fetching and storing basic user information from your service API.
Authentication flow

IFTTT’s protocol supports OAuth2 authentication, including support for refresh tokens if so desired.

Your service API should use access tokens for authentication and as a source of identity. A single access token should correspond to a single user account or resource owner on your service.

If refresh tokens are used, they must be non-expiring. If refresh tokens are not used, access tokens must be non-expiring.

IFTTT client credentials

When configuring your service, provide IFTTT with a client ID and client secret for authentication-related requests.

IFTTT authorization
Request

To begin authentication, IFTTT redirects the user to your OAuth2 Authorization URL, specified in the Service Authentication settings, and makes the following request:

Request
  • Method
    GET
    URL
    Your OAuth2 Authorization URL
Parameters
  • client_id
    IFTTT’s client ID for your service as set in your service configuration.
    response_type
    code
    scope

    ifttt

    The ifttt scope should provide access to resources for every trigger and action in your service. This way, users will not need to repeat the authentication flow to use all of your triggers and actions.

    You may override this parameter by specifying your own scope in the OAuth2 Authorization URL specified in the Service Authentication settings.

    state
    An anti-forgery token provided by IFTTT.
    redirect_uri

    https://ifttt.com/channels/{{service_id}}/authorize

    service_id is a string used to represent your service in URLs. You can set in your service configuration.

    Though we provide the redirect_uri parameter, we encourage you to register and use the redirect URL described in Step 3 over simply redirecting users to the parameter’s value.

Example
  • https://api.example-service.org/oauth2/authorize?client_id=94b26e58a3a88d5c&response_type=code&redirect_uri=https%3A%2F%2Fifttt.com%2Fchannels%2Fexample_channel%2Fauthorize&scope=ifttt&state=a00caec8dbd08e50
Response

After the user is redirected to your authorization request endpoint, you should authenticate the user and prompt to grant IFTTT access to the user’s resources on your service.

Authorization grant

Once a user authorizes IFTTT, you should redirect the user to IFTTT’s channel authorization URL along with an authorization code which IFTTT can exchange for a bearer token in the next step.

Redirect
URL
  • https://ifttt.com/channels/{{service_id}}/authorize
    The `service_id` is a string used to represent your service in URLs. You can set it in your service configuration.
Parameters
  • code
    The authorization code you generated.
    state
    The anti-forgery token provided by IFTTT in Step 2.
Example
  • https://ifttt.com/channels/example_channel/authorize?code=67a8ad40341224c1&state=a00caec8dbd08e50
User denies IFTTT

Should the user deny IFTTT access to your service, you should redirect them to IFTTT indicating access was denied.

Request
  • URL
    https://ifttt.com/channels/{{service_id}}/authorize
    service_id is a string used to represent your service in URLs. You can set it in your service configuration.
    Parameters

    error access_denied

Example
  • https://ifttt.com/channels/example_channel/authorize?error=access_denied
Token exchange
Request

After IFTTT has received an authorization code for the user, it will make a POST request to your OAuth2 Token URL, specified in the Service Authentication settings, and exchange the code for an access token.

Body Parameters
  • grant_type
    authorization_code
    code
    The authorization code generated in Step 3.
    client_id
    IFTTT’s client ID for your service as set in your service configuration.
    client_secret
    IFTTT’s client secret for your service as set in your service configuration.
    redirect_uri
    https://ifttt.com/channels/{{service_id}}/authorize
    service_id is a string used to represent your service in URLs. You can set it in your service configuration.
Example
  • 
    POST /oauth2/token HTTP/1.1
    Host: api.example-service.com
    Content-Type: application/x-www-form-urlencoded
    
    grant_type=authorization_code&code=67a8ad40341224c1&client_id=83465ab42&client_secret=c4f7defe91df9b23&redirect_uri=https%3A//ifttt.com/channels/service_id/authorize
    
    
Response

If the authorization code is not valid, respond with a 401 status code and error response body. If the the authorization code is valid, provide the following response:

HTTP
  • Status
    200
    Headers
    Content-Type application/json; charset=utf-8
Body
  • token
    Bearer
    access_token
    A token IFTTT will use to make authenticated calls to your API.
    refresh_token
    (optional) If enabled, refresh token IFTTT will use to refresh access tokens.
Example
  • 
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {
      "token_type": "Bearer",
      "access_token": "b29a71b4c58c22af116578a6be6402d2"
    }
    
    

Refresh Tokens

You can indicate that your API uses refresh tokens under the “Authentication” tab. IFTTT will continue to use an access token until a 401 is received indicating the token is no longer valid. Once this occurs IFTTT will attempt to obtain a new access token using a refresh token via the token refresh endpoint before attempting the request again.

Please note that refresh tokens cannot have a time-based expiry. The only time it is technically permissible for a refresh token to expire is after an access token has been refreshed. At that time, it is acceptable to return a new refresh token; however, we require that the previous refresh token not immediately expire.

Token refresh
Request

After token expiry, IFTTT will make a POST request to your OAuth2 Token Endpoint, specified in the Service Authentication settings, and use the refresh token to retrieve a new access token.

HTTP
  • Method
    POST
    URL
    OAuth2 Token Endpoint
    Headers
    Content-Type application/x-www-form-urlencoded
Body
  • grant_type
    refresh_token
    client_id
    IFTTT’s client ID for your service as set in your service configuration.
    client_secret
    IFTTT’s client secret for your service as set in your service configuration.
    refresh_token
    The refresh token retrieved in Step 4 of the Authentication Flow
Example
  • 
    POST /oauth2/token HTTP/1.1
    Host: api.example-service.com
    Content-Type: application/x-www-form-urlencoded
    
    grant_type=refresh_token&client_id=83465ab42&client_secret=c4f7defe91df9b23&refresh_token=c8764378d9879ffeadfcc233effafb23bbdbfe
    
    
Response

If the refresh token is not valid, respond with a 401 status code and error response body. If the the refresh token is valid, provide the following response:

HTTP
  • Status
    200
    Headers
    Content-Type: application/json; charset=utf-8
Body
  • access_token
    The updated access token.
Example
  • 
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {
      "access_token": "c547cdfecf7e86cde678bc87de6fc87",
      "refresh_token": "d7676beda76c38762349bac98cba799"
    }
    
    

User information

Request

After acquiring an access token, IFTTT will make a request to your user information endpoint. This information is considered private, and will only be displayed to the user who activated your service.

Occasionally, IFTTT will make requests to this endpoint to verify that the user’s access token is still valid.

HTTP
  • Method
    GET
    URL
    {{api_url_prefix}}/ifttt/v1/user/info
    Headers
    
    Authorization: Bearer {{user_access_token}}
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    X-Request-ID: {{random_uuid}}
    
Body
  • access_token
    The updated access token.
Example
  • 
    GET /ifttt/v1/user/info HTTP/1.1
    Host: api.example-service.com
    Authorization: Bearer b29a71b4c58c22af116578a6be6402d2
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    X-Request-ID: 434d757081c94013b1b28f2087d28a98
    
    
Response

Requests to the user information endpoint should generate the following response:

HTTP
  • Status
    200
    Headers
    Content-Type: application/json; charset=utf-8

The body of the response is a JSON object with one top-level field, data, with three fields:

Body
  • name
    (string) Full name, username, email, or other identification to display to the user.
    id
    (string) Username, email, number, or other identification to uniquely identify the resource owner within your service.
    url
    (optional string) URL to user’s dashboard or configuration page on your service’s website.
Example
  • 
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {
      "data":  {
        "name": "Walter White",
        "id": "heisenberg",
        "url": "http://example.com/users/heisenberg"
      }
    }
    
    

As with all other endpoints which require authentication via access token, you should return a 401 status to indicate that the access token is invalid or expired.

Triggers

Each trigger requires a unique API endpoint. For each Applet using a given trigger, IFTTT will poll that trigger’s endpoint once about every 15 minutes. For each new item returned by the trigger, IFTTT will fire the Applet’s associated action.

A trigger endpoint should return (by default) up to the 50 most recent events, regardless of whether or not we have seen them before. The number of returned items can be overriden by us by specifying a limit parameter in the request. Please do not limit the number of events returned except as specified by the limit parameter in the request. Events should remain on the timeline indefinitely and should not expire, although they may roll off the bottom of the list once the timeline exceeds 50 items.

Note that if the Realtime API is used for a given trigger, it will be polled at a longer period.

Request

To fetch new items IFTTT will make the following request to your trigger endpoints:

HTTP
  • Method
    POST
    URL
    {{api_url_prefix}}/ifttt/v1/triggers/{{trigger_slug}}
Headers Authenticated Services
  • 
    Authorization: Bearer {{user_access_token}}
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    Content-Type: application/json
    X-Request-ID: {{random_uuid}}
    
Headers Non-Authenticated Services
  • 
    IFTTT-Service-Key: {{ifttt_service_key}}
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    Content-Type: application/json
    X-Request-ID: {{random_uuid}}
    
Body
  • trigger_identity
    (string) A unique identifier for this set of trigger fields for a given Applet (see Trigger Identity).
    triggerFields
    (object) Map of trigger field slugs to values.
    limit
    (optional integer) Maximum number of items to be returned, default 50.
    user
    (object) Information about the IFTTT user related to this request.
    ifttt_source
    (optional object) Information about the personal Applet on IFTTT that triggered this request. If present, this will have an id uniquely identifying the Applet and a url pointing to a web page describing it. Note that only the user will be able to see this page, since personal Applets are private. In the future, these fields may point to an entity other than a personal Applet.

This example excludes the optional limit parameter. Only the 50 most recent items should be returned, in descending chronological order.

EXAMPLE: default limit
  • 
    POST /ifttt/v1/triggers/new_photo_in_album_with_hashtag HTTP/1.1
    Host: api.example-service.com
    Authorization: Bearer b29a71b4c58c22af116578a6be6402d2
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    Content-Type: application/json
    X-Request-ID: 7f7cd9e0d8154531bbf36da8fe24b449
    
    {
      "trigger_identity": "92429d82a41e93048",
      "triggerFields": {
        "album_name": "Street Art",
        "hashtag": "banksy"
      },
      "ifttt_source": {
        "id": "2",
        "url": "https://ifttt.com/myrecipes/personal/2"
      },
      "user": {
        "timezone": "Pacific Time (US & Canada)"
      }
    }
    

This example provides the limit parameter.

EXAMPLE: explicit limit
  • 
    POST /ifttt/v1/triggers/new_photo_in_album_with_hashtag HTTP/1.1
    Host: api.example-service.com
    Authorization: Bearer b29a71b4c58c22af116578a6be6402d2
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    Content-Type: application/json
    X-Request-ID: 7f7cd9e0d8154531bbf36da8fe24b449
    
    {
      "triggerFields": {
        "album_name": "Street Art",
        "hashtag": "banksy"
      },
      "limit": 10,
      "ifttt_source": {
        "id": "2",
        "url": "https://ifttt.com/myrecipes/personal/2"
      },
      "user": {
        "timezone": "Pacific Time (US & Canada)"
      }
    }
    
Response

Responses contain an array of item objects. Items are a stream of unique events on a timeline, and each item has:

  • One field for every ingredient in the trigger.
  • A unique identifier used to prevent Applet from firing more than once on the same item.
  • A timestamp in Unix seconds. Items in the stream must be in descending order by the timestamp.

Responses should be structured as follows:

HTTP
  • Status
    200
    Headers
    Content-Type application/json; charset=utf-8

For the Body you get a JSON object which contains an array, data, of item objects. Items have one key-value pair for each ingredient slug and value, and a meta object with two fields:

BODY
  • 
      "data": [
        {
          "slug 1": "value for ingredient 1",
          "slug 2": "value for ingredient 2",
          ...
          "slug n": "value for ingredient n",
          "meta": {
            "id": "14b9-1fd2-acaa-5df5", //(string) a unique identifier for the item.
            "timestamp": 1383597267 // (integer) a Unix timestamp in seconds.
          }
        }
      ]
    
Response Example
  • 
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {
      "data": [
        {
          "image_url": "http://example.com/images/128",
          "tags": "banksy, brooklyn",
          "posted_at": "2013-11-04T09:23:00-07:00"
          "meta": {
            "id": "14b9-1fd2-acaa-5df5",
            "timestamp": 1383597267
          }
        },
        {
          "image_url": "http://example.com/images/125",
          "tags": "banksy, nyc",
          "posted_at": "2013-11-04T03:23:00-07:00"
          "meta": {
            "id": "ffb27-a63e-18e0-18ad",
            "timestamp": 1383596355
          }
        }
      ]
    }
    
Date and time ingredients

Ingredients that use the Date or Date with time are timestamps in the W3 flavor of ISO8601 formats.

Example: Date only
  • 2013-12-31
    2014-01-01
Example: Date & Time
  • 2013-11-04T09:23:00Z
    2013-11-04T09:23:00-07:00

Trigger Identity

A trigger_identity field is sent with every trigger endpoint request and can be thought of as unique signature of a specific user, trigger, and trigger fields. For example, if a user has multiple Applets with the same trigger fields/values they will each have the same trigger_identity.

Note that this field can safely be ignored. However, it becomes powerful when used to notify your API that a user no longer has any Applets with a given trigger_identity.

Example

Consider the following hypothetical publish/subscribe scenario for a connected car product:

  1. A user creates an Applet (or many Applets) that trigger on “Check Engine Light”.
  2. The trigger endpoint is called and the API stores the trigger_identity for that user and associates that value with a “Check Engine Light” event on their vehicle.
  3. The API notifies the vehicle that it wants to subscribe to “Check Engine Light” events and the vehicle begins sending this data to the cloud.
  4. At some point in the future, a user deletes or updates their Applet(s) such that they no longer have any Applets that trigger on the event “Check Engine Light”.
  5. IFTTT calls the DELETE endpoint (example below).
  6. The API does a lookup on trigger_identity for that user and notifies the associated vehicle to stop sending “Check Engine Light” events.
  7. The API may then clean up or remove the storage of all the events associated with “Check Engine Light” for that user.
Request
HTTP
  • Method
    Delete
    URL
    {{api_url_prefix}}/ifttt/v1/triggers/{{trigger_slug}}/trigger_identity/{{trigger_identity}}
Headers (authenticated services)
  • 
    Authorization: Bearer {{user_access_token}}
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    Content-Type: application/json
    X-Request-ID: {{random_uuid}}
    
Example
  • 
    DELETE /ifttt/v1/triggers/new_photo_in_album_with_hashtag/trigger_identity/92429d82a41e93048 HTTP/1.1
    Host: api.example-service.com
    Authorization: Bearer b29a71b4c58c22af116578a6be6402d2
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    Content-Type: application/json
    X-Request-ID: 7f7cd9e0d8154531bbf36da8fe24b449
    

Realtime API

With IFTTT’s Realtime API, you can have Applets involving user-oriented triggers from your service run near-instantly. Simply write a hook to notify IFTTT of any changes related to a given user which would correspond to a trigger they may be using. Rather than sending data directly, the Realtime API is used to notify IFTTT that there are new events available at your service for a specific user_id or trigger identity that we can then fetch through polling.

If you notify IFTTT that you are utilizing the Realtime API, we can limit the load on your service by polling less frequently.

Note that you will be able to tell that a trigger was checked by a Realtime notification by the presence of the X-IFTTT-Realtime: 1 header in the trigger check request.

Request

You can find your Service Key under the “Details” tab. Include it in your IFTTT-Service-Key header to immediately start making Realtime requests.

We also recommend that you send an X-Request-ID header with a UUID. Should the need to debug arise in the future, this will help reconcile server logs.

HTTP
  • Method
    POST
    URL
    https://realtime.ifttt.com/v1/notifications
Headers
  • 
    IFTTT-Service-Key: {{ifttt_service_key}}
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    Content-Type: application/json
    X-Request-ID: {{random_uuid}}
    

A JSON object which contains an array, data, of objects which each have a user_id or trigger_identity:

Body
  • data[user_id]
    (string) The same id for the user that is returned by your user information endpoint.
    data[trigger_identity]
    (string) A unique identifier for a given set of trigger fields, sent to your API with every trigger endpoint request.

Using trigger_identity will improve the performance of your integration with IFTTT. When the IFTTT Realtime API receives a user_id each of that user's triggers must be polled for, even though likely only a few of them have fresh data. For example, if a user had 100 Applets using your service's triggers, when that user_id is sent to the Realtime API IFTTT will need to run 100 checks for fresh data. This is a lot of extra time spent processing for both you and IFTTT, and reducing this time means your users' Applets will run faster. By using trigger_identity, IFTTT can poll your service for only the relevant fresh data.

The Realtime request can contain up to 1000 user_ids and/or trigger_identities, although generally one would send either all user_ids or all trigger_identitys:

Example
  • 
    POST /v1/notifications HTTP/1.1
    Host: realtime.ifttt.com
    IFTTT-Service-Key: WlWFGKXFsXBaFMt8yZ7aLOafdqo7mAhY
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    Content-Type: application/json
    X-Request-ID: 619fd42930f74b78abc4394ca7bfec5b
    
    {
      "data": [
        {
          "user_id": "23489759"
        },
        {
          "user_id": "77956024"
        },
        {
          "trigger_identity": "c5559d12d393b25c140364d891292e02233933a5"
        },
        ...
      ]
    }
    

Trigger fields

Trigger fields can have dynamic options and dynamic validation. Each dynamic option and validation requires a unique endpoint. However, it is possible to validate all trigger fields using a single unique endpoint using contextual validation.

Trigger field dynamic options

Options have both a label, which the user sees, and a value, which is sent when the trigger is executed. Options can be placed into categories; users may select categorized options but may not select the category itself. See the example exchange below for more information on how to present the options to IFTTT.

Request

For drop-down selector trigger fields, you can dynamically provide user-specific options. Each time the drop-down is displayed, IFTTT will fetch a list of options from your trigger field’s dynamic options endpoint.

HTTP
  • Method
    POST
    URL
    {{api_url_prefix}}/ifttt/v1/triggers/{{trigger_slug}}/fields/{{trigger_field_slug}}/options
HEADERS: authenticated services
  • 
    Authorization: Bearer {{user_access_token}}
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    X-Request-ID: {{random_uuid}}
    
HEADERS: non-authenticated services
  • 
    IFTTT-Service-Key: {{ifttt_service_key}}
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    X-Request-ID: {{random_uuid}}
    
Example
  • 
    POST /ifttt/v1/triggers/new_photo_in_album_with_hashtag/fields/album_name/options HTTP/1.1
    Host: api.example-service.com
    Authorization: Bearer b29a71b4c58c22af116578a6be6402d2
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    X-Request-ID: 37ccb881af5542fe8c5534e9744b6116
    
    {}
    
Response

Your trigger field’s dynamic options endpoint should generate the following response:

HTTP
  • Status
    200
    Headers
    Content-Type: application/json; charset=utf-8

A JSON object which contains an array, data, of option objects:

Body
  • label
    (string) A user-facing label.
    value
    (string) The actual field value.
Example
  • 
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {
      "data": [
        {
          "label": "Street Art",
          "value": "12345"
        },
        {
          "label": "Technology",
          "value": "43245"
        },
        {
          "label": "Animals",
          "values": [
            {
              "label": "Cats",
              "value": "32143"
            },
            {
              "label": "Dogs",
              "value": "51231"
            }
          ]
        }
      ]
    }
    
Trigger field dynamic validation
Request

For text trigger fields, you can dynamically validate user input. IFTTT will make the following request to your service API:

HTTP
  • Method
    POST
    URL
    {{api_url_prefix}}/ifttt/v1/triggers/{{trigger_slug}}/fields/{{trigger_field_slug}}/validate
HEADERS: authenticated services
  • 
    Authorization: Bearer {{user_access_token}}
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    X-Request-ID: {{random_uuid}}
    
HEADERS: non-authenticated services
  • 
    IFTTT-Service-Key: {{ifttt_service_key}}
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    X-Request-ID: {{random_uuid}}
    
Body
  • value
    (string) User input to be validated
Example
  • 
    POST /ifttt/v1/triggers/new_photo_in_album_with_hashtag/fields/album_name/validate HTTP/1.1
    Host: api.example-service.com
    Authorization: Bearer b29a71b4c58c22af116578a6be6402d2
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    Content-Type: application/json
    X-Request-ID: b959f481ef4f4a8ab0ec414f58991674
    
    {
      "value": "Street Art"
    }
    
Response

Your trigger field’s dynamic validation endpoint should generate the following response:

HTTP
  • Status
    200, regardless of whether or not the user input is valid
    Headers
    Content-Type: application/json; charset=utf-8

For the body you get a JSON object which contains an object, data:

Body
  • data[valid]
    (boolean) Validity of user’s input.
    data[message]
    (optional string) Explanation to display to user if input was invalid.
Example: Valid Input
  • 
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {
      "data":  {
        "valid": true
      }
    }
    
Example: Invalid Input
  • 
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {
      "data":  {
        "valid": false,
        "message": "Sorry, no album exists with the name \"Street Art\"."
      }
    }
    
Trigger field contextual validation

Contextual Validation allows you to validate a trigger field based on the values of other trigger fields. It is incredibly useful for validating multiple trigger fields in a single API call. Because Contextual Validation is a trigger setting, validation will be available to every trigger field. When Contextual Validation is enabled, all trigger field dynamic validation endpoints for the trigger will not be used in favor of the single validate endpoint.

To enable this option for your trigger, please contact support.

Request

IFTTT will make the following request to your service API:

HTTP
  • Method
    POST
    URL
    {{api_url_prefix}}/ifttt/v1/triggers/{{trigger_slug}}/validate
HEADERS: authenticated services
  • 
    Authorization: Bearer {{user_access_token}}
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    X-Request-ID: {{random_uuid}}
    
HEADERS: non-authenticated services
  • 
    IFTTT-Service-Key: {{ifttt_service_key}}
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    X-Request-ID: {{random_uuid}}
    
Body
  • values
    (object) Trigger fields with their values
Example
  • 
    POST /ifttt/v1/triggers/new_comment_on_card/validate HTTP/1.1
    Host: api.example-service.com
    Authorization: Bearer b29a71b4c58c22af116578a6be6402d2
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    Content-Type: application/json
    X-Request-ID: b959f481ef4f4a8ab0ec414f58991674
    
    {
      "values": {
        "board": "New Features",
        "card": "Potential Ideas"
      }
    }
    
Example

The use of contextual validation comes in handy when a trigger field needs to be validated, but the validation depends on another trigger field. Take the following scenario:

  1. The trigger has two trigger fields, board and card.
  2. The board name is unique, and a card exists within a board. However, cards can have the same name across different boards.
  3. Validating that the card exists becomes simple because the value of board is known.

If dynamic validation is used for the card trigger field, it is difficult to know which card the user intends to trigger on during validation if the user has multiple cards with the same name.

Response

Your trigger’s contexual validation endpoint should generate the following response:

HTTP
  • Status
    200, regardless of whether or not the user input is valid
    Headers
    Content-Type: application/json; charset=utf-8

For the body you get a JSON object which contains an object, data:

Body
Example: Valid Input
  • 
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {
      "data":  {
        "board":  {
          "valid": true
        },
        "card":  {
          "valid": true
        }
      }
    }
    
Example: Invalid Input
  • 
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {
      "data":  {
        "board":  {
          "valid": true
        },
        "card":  {
          "valid": false,
          "message": "Sorry, no card exists with the name \"Potential Ideas\" in the "New Features" board."
        }
      }
    }
    

Applet Templates

When you create a new trigger and define the data the trigger will make available via ingredients, we'll ask you to provide examples of how the trigger would be best used in various categories of actions. This helps to guide users create powerful Applets more efficiently from helpful defaults instead of empty fields.

Below you'll find helpful tips for each of the action categories:

📱 Mobile push notification tips:

  • Should be friendly and personal! Use 'you' instead of 'my'.
  • Don't make the content too dense. Inform the user of the most important information about the event.
  • Avoid ingredients that point to URLs.

💬 Short message tips:

  • Provide the most important information using ingredients that keep the message contextual to the event.
  • Keep in mind that the message might be truncated based on character restrictions.
  • Include a URL ingredient if one is available.

📜 Long post tips:

  • Use the 'Post body' field to craft a delightful message for users. HTML is accepted, so be sure to add formatting that might enhance the message.
  • Keep in mind that this content is used in email actions, which are widely used. 'Post title' is the subject and 'Post body' is the body of the email.

📃 Plaintext file tips:

  • Plaintext files are great for record keeping. Be sure to use all relevant ingredients in the 'Plaintext body'.
  • If the 'Filename' is static (ex. Saved tracks on Spotify), one document will be created and then appended to for each subsequent event.
  • If the 'Filename' contains a dynamic ingredient (ex. Track saved on {{SavedAt}}), a new file will be created with each event because it will have a unique filename.
  • The 'Folder path' specified will be created if it does not yet exist for the user.

📊 Spreadsheet tips:

  • Spreadsheets are great for record keeping. Be sure to use all relevant ingredients.
  • Use ||| to separate cells in a row of a spreadsheet (ex. "{{Ingredient1}}|||{{Ingredient2}}|||{{Ingredient3}}")
  • If you would like to use an image in one of the cells use =IMAGE("{{ingredient}}";1).

🗣 Phone call tips:

  • The contents here will be read aloud when the phone call action runs. Keep that in mind when formatting the template.
  • A good starting place for this template is to reference the contents you wrote for the notification template.

📅 Calendar event tips:

  • You need to have at least one timestamp ingredient included in the 'Quick add text' so that the calendar action knows when to create the event.
  • If your trigger produces the start time and end time of the event, be sure to use both ingredients in the template (ex. "Some event occurred from {{StartTime}} to {{EndTime}}")

Actions

Each action requires a unique API endpoint.

Request

For each new trigger item, IFTTT will push data to your action endpoint with the following request structure:

HTTP
  • Method
    POST
    URL
    {{api_url_prefix}}/ifttt/v1/actions/{{action_slug}}
HEADERS: authenticated services
  • 
    Authorization: Bearer {{user_access_token}}
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    Content-Type: application/json
    X-Request-ID: {{random_uuid}}
    
HEADERS: non-authenticated services
  • 
    IFTTT-Service-Key: {{ifttt_service_key}}
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    Content-Type: application/json
    X-Request-ID: {{random_uuid}}
    
Body
  • actionFields
    (object) Map of action field slugs to values.
    user
    (object) Information about the IFTTT user related to this request.
    ifttt_source
    (optional object) Information about the personal Applet on IFTTT that triggered this request. If present, this will have an id uniquely identifying the Applet and a url pointing to a web page describing it. Note that only the user will be able to see this page, since personal Applets are private. In the future, these fields may point to an entity other than a personal Applet.
Example
  • 
    POST /ifttt/v1/actions/new_status_update HTTP/1.1
    Host: api.example-service.com
    Authorization: Bearer b29a71b4c58c22af116578a6be6402d2
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    Content-Type: application/json
    X-Request-ID: 1d21c3cd2ed8441ea269dd554d2c8e54
    
    {
      "actionFields": {
        "title": "New Banksy photo!",
        "body": "Check out a new Bansky photo: http://example.com/images/125"
      },
      "ifttt_source": {
        "id": "2",
        "url": "https://ifttt.com/myrecipes/personal/2"
      },
      "user": {
        "timezone": "Pacific Time (US & Canada)"
      }
    }
    
Response

Your action endpoint should generate the response below:

HTTP
  • Status
    200
    Headers
    Content-Type: application/json; charset=utf-8

A JSON object which contains an array, data, of a single item object:

HTTP
  • data[0][id]
    (string) A database ID, timestamp, URL, or other value which uniquely identifies the resource created or modified during action execution.
    data[0][url]
    (optional string) URL to the created or modified resource.
Example
  • 
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {
      "data": [
        {
          "id": "234325",
          "url": "http://example.com/posts/234325"
        }
      ]
    }
    
Skipping Actions

If an action fails and returns an error, IFTTT will retry several times. If the action continues to fail, the offending event will eventually be skipped. However, the action can specify that a event be skipped immediately by responding with status code 400 and a special error object. It should do this when a event will simply never be successfully processed because it is invalid or unacceptable. For example, a “Post Comment” action may want to skip over any events that have an empty comment. Note that this does not include syntactic errors in the requests or problems beyond just the individual event and its action fields, including authentication.

A “skip” error has a property status that must always be set to "SKIP". It should also have a property message. This message should be a helpful user-facing error message as it may be displayed to users in their logs and elsewhere. 400 responses may have multiple error objects; any additional “SKIP” objects after the first will be ignored.

Example
  • 
    HTTP/1.1 400 Bad request
    Content-Type: application/json; charset=utf-8
    
    {
      "errors": [
        {
          "status": "SKIP",
          "message": "Audio file size too big"
        }
      ]
    }
    

Action fields

Action fields can have dynamic options. Each dynamic option requires a unique endpoint. Unlike trigger fields, action fields do not currently support dynamic validation.

Action field dynamic options

Options have both a label, which the user sees, and a value, which is sent when the action is executed. Options can be placed into categories; users may select categorized options but may not select the category itself. See the example exchange below for more information on how to present the options to IFTTT.

Request

For drop-down selector action fields, you can dynamically provide user-specific options. Each time the action field is displayed, IFTTT will fetch a list of options from your action field’s dynamic options endpoint:

HTTP
  • Method
    POST
    URL
    {{api_url_prefix}}/ifttt/v1/actions/{{action_slug}}/fields/{{action_field_slug}}/options
HEADERS: authenticated services
  • 
    Authorization: Bearer {{user_access_token}}
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    X-Request-ID: {{random_uuid}}
    
HEADERS: non-authenticated services
  • 
    IFTTT-Service-Key: {{ifttt_service_key}}
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    X-Request-ID: {{random_uuid}}
    

An empty JSON object

Body
  •  
    {}
Example
  • 
    POST /ifttt/v1/actions/post_photo_to_album/fields/album_name/options HTTP/1.1
    Host: api.example-service.com
    Authorization: Bearer b29a71b4c58c22af116578a6be6402d2
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    X-Request-ID: 9f99e73452cd40198cb6ce9c1cde83d6
    
    {}
    
Response

Your action field’s dynamic options endpoints should generate the following response:

HTTP
  • Status
    200
    Headers
    Content-Type: application/json; charset=utf-8

For the body you will get a JSON object which contains an array, data, of option objects:

Body
  • data[label]
    (string) A user-facing label.
    data[value]
    (string) The actual field value.
Example
  • 
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {
      "data": [
        {
          "label": "Street Art",
          "value": "12345"
        },
        {
          "label": "Technology",
          "value": "43245"
        },
        {
          "label": "Animals",
          "values": [
            {
              "label": "Cats",
              "value": "32143"
            },
            {
              "label": "Dogs",
              "value": "51231"
            }
          ]
        }
      ]
    }
    

Service status

Provide an API endpoint which IFTTT can periodically check for your service’s availability. This endpoint is not user-specific, and thus does not require an access token.

Request

IFTTT will make the following request to check you service’s API status:

HTTP
  • Method
    GET
    URL
    {{api_url_prefix}}/ifttt/v1/status
HEADERS
  • 
    IFTTT-Service-Key: {{ifttt_service_key}}
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    X-Request-ID: {{random_uuid}}
    
Example
  • 
    GET /ifttt/v1/status HTTP/1.1
    Host api.example-service.com
    IFTTT-Service-Key: vFRqPGZBmZjB8JPp3mBFqOdt
    Accept: application/json
    Accept-Charset: utf-8
    Accept-Encoding: gzip, deflate
    X-Request-ID: 0715f98e65f749aba2fc243eac1e3c09
    
Response

The service status endpoint should generate the following response:

HTTP
  • Status
    200 or 503
    Body
    none
Example: service OK
  • 
    HTTP/1.1 200 OK
    
Example: service unavailable
  • 
    HTTP/1.1 503 Unavailable
    

Next:

Test Your Service