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.
We also provide an OpenAPI definition file that describes the IFTTT Service API. You can use this file to generate some of your server code. This should save you time and effort implementing your service. See OpenAPI definition for more details.
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 authentication
If your service requires user authentication, users must connect your service before they can use its Applets.
Service authentication has two steps:
- Authentication flow. This step authorizes IFTTT to make requests to your service API on behalf of the user.
- Fetching and storing basic user information from your service API.
Note: If your service interacts with user data, authentication is required. Trigger/query/action fields designed to circumvent that requirement (ex. a user's API key) will not be approved.
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 queries, 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 always use the redirect URL provided in Authentication settings 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
Theservice_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 the original request.
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 earlier in this flow.
- 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 valid, provide the following response:
HTTP
-
- Status
- 200
- Headers
Content-Type application/json; charset=utf-8
Body
-
token_type
- 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" }
If the authorization code is not valid, respond with a 400 status code and body as shown in the following example:
HTTP
-
- Status
- 400
- Headers
Content-Type application/json; charset=utf-8
Body
-
error
- invalid_grant
error_description
- (optional) Description of the error. Do not disclose specific tokens or authentication codes here
Example
-
HTTP/1.1 400 OK Content-Type: application/json; charset=utf-8 { "error": "invalid_grant", "error_description": "The code or token used is not valid" }
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 the token exchange step 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 valid, provide the following response:
HTTP
-
- Status
- 200
- Headers
Content-Type: application/json; charset=utf-8
Body
-
access_token
- The updated access token.
refresh_token
- The updated refresh token.
Example
-
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { "access_token": "c547cdfecf7e86cde678bc87de6fc87", "refresh_token": "d7676beda76c38762349bac98cba799" }
If the refresh token is not valid, respond with a 400 status code and body as shown in the following example:
HTTP
-
- Status
- 400
- Headers
Content-Type application/json; charset=utf-8
Body
-
error
- invalid_grant
error_description
- (optional) Description of the error. Do not disclose specific tokens or authentication codes here
Example
-
HTTP/1.1 400 OK Content-Type: application/json; charset=utf-8 { "error": "invalid_grant", "error_description": "The code or token used is not valid" }
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}}
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) An unchangeable, permanent identifier to uniquely identify the resource owner within your service. We advise against using access tokens, emails, usernames, or phone numbers for this as the identifier cannot be changed. **Up to 200 characters.**
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 hour. For each new item returned by the trigger, IFTTT will fire the Applet’s associated action.
Note: To ensure a great Applet experience for your users, triggers are required to use the Realtime API if a user would expect its Applets to run in realtime.
A trigger endpoint should return (by default) the 50 most recent events, regardless of whether or not we have seen them before. The number of returned items can be overridden by IFTTT when a limit
parameter is present 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.
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": "America/Los_Angeles" } }
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": "America/Los_Angeles" } }
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 Applets 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 } } ] }
Trigger Identity
A trigger_identity
field is sent when an Applet is enabled and then with every subsequent trigger endpoint request. The trigger_identity
can be thought of as a unique signature of a specific user, trigger, and trigger fields. You should recieve a trigger check request with a trigger_identity
in the first minute after an Applet is enabled.
For example, if a user has multiple Applets with the same trigger fields/values they will each have the same trigger_identity
. We recommend that your service stores the relationship between a trigger_identity
and the specific user, trigger, and trigger fields to assist in troubleshooting.
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:
- A user creates an Applet (or many Applets) that trigger on “Check Engine Light”.
- The trigger endpoint is immediately called and the API stores the
trigger_identity
for that user and associates that value with a “Check Engine Light” event on their vehicle. - 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.
- 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”.
- IFTTT calls the
DELETE
endpoint (example below). - The API does a lookup on
trigger_identity
for that user and notifies the associated vehicle to stop sending “Check Engine Light” events. - 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
Response
HTTP
-
- Status
- 200
- Headers
-
Content-Type: application/json; charset=utf-8
Example
-
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8
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 your API does not support user authentication you can still leverage the Realtime API by relying on trigger identities alone.
Note: You still should return the limit
(50 by default) number of most recent events, not just the ones related to the Realtime notification you sent, regardless of whether or not we have seen them before.
If you are utilizing the Realtime API, we will limit the load on your service by performing trigger checks 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_id
s or all trigger_identity
s:
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 a dynamic validation of a text input, location-based input, or dynamic options via a drop-down.
With a drop-down, we provide two different choices:
- A dynamic drop-down selector. We provide you with a unique API endpoint based on the trigger field's name you can use to dynamically grab the list of options from your server.
- A manual drop-down to manually add a list of options that the user can select from.
It is possible to validate all trigger fields using a single unique endpoint using contextual validation.
Trigger field dynamic options
Dynamic dropdowns
Options have a label, which the user sees, and a value, which is sent when the trigger is executed. If you're using the dynamic drop-down instead of the manual drop-down, options can be placed into categories one level deep. Users may select categorized options but may not select the category itself.
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" } ] } ] }
Dynamic checkboxes
Options have a label, which the user sees, and a value, which is sent when the trigger is executed.
Request
For checkbox trigger fields, you can dynamically provide user-specific options. Each time the checkbox list 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:
- The trigger has two trigger fields,
board
andcard
. - The
board
name is unique, and acard
exists within aboard
. However, cards can have the same name across different boards. - Validating that the
card
exists becomes simple because the value ofboard
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 contextual 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
- (object) dynamic validation objects for each trigger field.
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." } } }
Location-based input
Location-based trigger fields enable users to specify whether Applets should run based on a point, an area, entering an area, exiting an area, or entering or exiting an area. These fields can be dynamically validated. Below is an example of how location-based fields are represented.
Example
-
"triggerFields": { "location": { "lat": 37.783923707779095, "lng": -122.40864549999998, "radius": 0, "address": "923 Market St, San Francisco, CA 94103, USA", "description": "923 Market St, San Francisco, CA 94103, USA", "zoom": 16 }, }
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. These examples should guide users to 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": "America/Los_Angeles" } }
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:
Body
-
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 be populated via a static text input or a drop-down. Unlike trigger fields, action fields do not currently support dynamic validation.
With a drop-down, we provide two different choices:
- A dynamic drop-down selector. We provide you with a unique API endpoint based on the action field's name you can use to dynamically grab the list of options from your server.
- A manual drop-down to manually add a list of options that the user can select from.
Action field dynamic options
Dynamic dropdowns
Options have a label, which the user sees, and a value, which is sent when the action is executed. If you're using the dynamic drop-down instead of the manual drop-down, options can be placed into categories one level deep. Users may select categorized options but may not select the category itself.
Request
For action fields using the dynamic drop-down selector, 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" } ] } ] }
Dynamic checkboxes
Options have a label, which the user sees, and a value, which is sent when the action is executed.
Request
For checkbox action fields, you can dynamically provide user-specific options. Each time the checkbox list 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" } ] } ] }
Queries
Each query requires a unique API endpoint.
Request
To fetch new query data IFTTT will make the following request to your query endpoint with the following request structure:
HTTP
-
- Method
- POST
- URL
{{api_url_prefix}}/ifttt/v1/queries/{{query_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
-
- queryFields
- (object) Map of query field slugs to values.
- cursor
- (optional string) Reference to the next page of the result set.
- limit
- (optional number) Max number of rows to return in a response, default 50.
- include
- (optional string array) Ingredient slugs to resolve and include in the query response.
- 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/queries/list_album_photos 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 { "queryFields": { "album_name": "Street Art" }, "ifttt_source": { "id": "2", "url": "https://ifttt.com/myrecipes/personal/2" }, "user": { "timezone": "America/Los_Angeles" } }
Response
Your query endpont should generate the response below:
HTTP
-
- Status
- 200
- Headers
Content-Type application/json; charset=utf-8
BODY
-
"data": [ { "slug 1": "value for row 1 ingredient 1", "slug 2": "value for row 1 ingredient 2", ... "slug n": "value for row 1 ingredient n" }, ... { "slug 1": "value for row n ingredient 1", "slug 2": "value for row n ingredient 2", ... "slug n": "value for row n ingredient n" }, ]
Responses should contain an array of rows. Each row should have one attribute for every ingredient in the query.
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" }, { "image_url": "http://example.com/images/125", "tags": "banksy, nyc", "posted_at": "2013-11-04T03:23:00-07:00" } ] }
Pagination
Queries should support pagination. A query request can have cursor
and/or limit
attributes that control pagination.
Example
-
POST /ifttt/v1/queries/list_album_photos 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 { "queryFields": { "album_name": "Street Art" }, "limit": 1, "ifttt_source": { "id": "2", "url": "https://ifttt.com/myrecipes/personal/2" }, "user": { "timezone": "America/Los_Angeles" } }
The response should contain limit
rows (default 50). If the result set is larger than the limit
, a cursor
should be present and reference the next page.
Paginated Response Example: page 1
-
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" } ], "cursor": "seijjh24ks" }
If used in a subsequent query request, cursor
should reference the next page of the result set.
Example
-
POST /ifttt/v1/queries/list_album_photos 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 { "queryFields": { "album_name": "Street Art" }, "limit": 1, "cursor": "seijjh24ks", "ifttt_source": { "id": "2", "url": "https://ifttt.com/myrecipes/personal/2" }, "user": { "timezone": "America/Los_Angeles" } }
The response should contain the next limit
rows of the result set. The last page should not have the cursor
attribute.
Paginated Response Example: page 2
-
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { "data": [ { "image_url": "http://example.com/images/125", "tags": "banksy, nyc", "posted_at": "2013-11-04T03:23:00-07:00" } ] }
Nested results
Most queries will have primitive ingredients (string, number...) and result in a tabular result set like in the examples above. However, a query can have complex ingredients that are queries themselves resulting in nested result sets.
Such query ingredients can be represented in one of the two ways: unresolved or resolved.
An unresolved query ingredient will have a subquery request as the ingredient value. A client can use that request later in a subsequent query request to drill-down into the result set.
A resolved query ingredient will have a subquery result as the ingredient value. It's a result of executing the query associated with that ingredient.
The request attribute include
can be used to control which one of the two representations the query ingredient should have in the query response.
The following is an example that demonstrates both scenarios. Here we request a list of images. We also request likes
to be included with each image.
Example
-
POST /ifttt/v1/queries/list_album_photos 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 { "queryFields": { "album_name": "Street Art" }, "include": ["likes"], "ifttt_source": { "id": "2", "url": "https://ifttt.com/myrecipes/personal/2" }, "user": { "timezone": "America/Los_Angeles" } }
The response should contain a resolved likes
subquery and unresolved dislikes
subquery. In both cases inclusion of the queryFields
attribute is mandatory.
Response Example: resolved subquery
-
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", "likes": { "queryFields": { "image_url": "http://example.com/images/128" }, "data": [ { "date": "2013-11-04T09:23:00-07:00", "user": "jim" }, { "date": "2013-11-04T09:03:00-07:00", "user": "bob" } ] }, "dislikes": { "queryFields": { "image_url": "http://example.com/images/128" } } } ] }
Trigger-based queries
If your service was published before August 2020, trigger-based queries may have been added to your service. These queries use the response from your trigger endpoint and translates it to a query that can be used in Applets and connections.
For example, if you had a trigger named New event added, the query based on this trigger would be History of new events added.
Query fields
Query fields can have dynamic options via a drop-down or static text input. Each dynamic option requires a unique endpoint.
Query field dynamic options
Options have both a label, which the user sees, and a value, which is sent when the query 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 query fields, you can dynamically provide user-specific options. Each time the query field is displayed, IFTTT will fetch a list of options from your query field’s dynamic options endpoint:
HTTP
-
- Method
- POST
- URL
{{api_url_prefix}}/ifttt/v1/queries/{{query_slug}}/fields/{{query_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/queries/list_album_photos/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 query 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" } ] } ] }
Ingredients
An ingredient is a data point returned by a trigger or a query. Typically a response will have multiple sets of data points. You can think of a response as a tabular data set with items of the data
attribute as rows, and ingredients as columns.
BODY
-
"data": [ { "ingredient 1": "value for row 1 ingredient 1", "ingredient 2": "value for row 1 ingredient 2", ... "ingredient n": "value for row 1 ingredient n" }, ... { "ingredient 1": "value for row n ingredient 1", "ingredient 2": "value for row n ingredient 2", ... "ingredient n": "value for row n ingredient n" }, ]
The response above can be represented as a table
ingredient 1 | ingredient 2 | ... | ingredient n |
---|---|---|---|
value for row 1 ingredient 1 | value for row 1 ingredient 2 | ... | value for row 1 ingredient n |
value for row 2 ingredient 1 | value for row 2 ingredient 2 | ... | value for row 2 ingredient n |
... | ... | ... | ... |
value for row n ingredient 1 | value for row n ingredient 2 | ... | value for row n ingredient n |
String ingredients
Ingredients that use the String, Image URL, Web URL, or File URL are simple strings.
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
Nested ingredients
Ingredients that use the Query are queries themselves. They are available in queries only and described in more detail in Nested results.
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 your 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
OpenAPI definition
We provide an OpenAPI definition file that describes the IFTTT Service API. You can use this file to generate some of your server code. This should save you time and effort implementing your service.
What is OpenAPI
OpenAPI (formerly Swagger) is a standard used to describe an API.
How to use it
There are multiple tools that can generate server code from an OpenAPI definition file. The choice of tool will depend on your tech stack and requirements. OpenAPI Generator and Swagger Codegen are the most popular ones.
For this example we'll use OpenAPI Generator Gradle Plugin to generate server stubs for a Spring Boot application.
Initialize a gradle project
-
$ mkdir service-api-example $ cd service-api-example $ gradle wrapper --gradle-version 6.7.1 $ mkdir -p src/main/resources $ mkdir -p src/main/java/com/example/service/
Create build.gradle
-
plugins { id 'org.openapi.generator' version '4.3.1' id 'org.springframework.boot' version '2.3.4.RELEASE' id 'io.spring.dependency-management' version '1.0.10.RELEASE' id 'java' } group = 'com.example.service' version = '0.0.1-SNAPSHOT' repositories { mavenCentral() } // Configuration for the OpenAPI Generate Gradle Plugin openApiGenerate { // OpenAPI definition file location inputSpec = "${projectDir}/src/main/resources/service-api.yaml" // Which generator to use (see https://openapi-generator.tech/docs/generators#server-generators) generatorName = 'spring' // https://openapi-generator.tech/docs/generators/spring configOptions = [ dateLibrary : "java8", interfaceOnly : "true", skipDefaultInterface: "false", openApiNullable : "false", apiPackage : "${group}.${name}", modelPackage : "${group}.${name}.model", ] } sourceSets.main.java.srcDirs += 'build/generate-resources/main/src/main/java' dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' implementation 'org.springframework:spring-webmvc:5.2.9.RELEASE' implementation 'io.swagger:swagger-annotations:1.6.2' implementation 'javax.validation:validation-api:2.0.1.Final' implementation 'com.fasterxml.jackson.core:jackson-annotations:2.11.3' implementation 'org.openapitools:jackson-databind-nullable:0.2.1' implementation 'javax.annotation:javax.annotation-api:1.3.2' compileOnly 'javax.servlet:javax.servlet-api:4.0.1' }
Download OpenAPI definition for IFTTT Service API into src/main/resources/service-api.yaml
.
Generate server stubs ./gradlew openApiGenerate
.
You should be able to find generated code at build/generate-resources/main/src/main/java/com/example/service/service_api_example/IftttApi.java
.
Now we can add our own implementation. For this example we'll implement just one endpoint: /ifttt/v1/status
.
Create API implementation src/main/java/com/example/service/IftttApiController.java
-
package com.example.service; import com.example.service.service_api_example.IftttApi; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RestController; @RestController public class IftttApiController implements IftttApi { @Override public ResponseEntity
getStatus() { return ResponseEntity.ok().build(); } }
Create the main class src/main/java/com/example/service/Application.java
-
package com.example.service; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
Run the app ./gradlew bootRun
.
Check the app status curl --verbose localhost:8080/ifttt/v1/status
. You should see a successful 200 response with no body.
Next steps:
- Learn about testing your service.
- Explore the Connect API.