CINXE.COM
Userflow API Reference
<!doctype html> <html> <head> <meta charset="utf-8"> <meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <title>Userflow API Reference</title> <style> .highlight table td { padding: 5px; } .highlight table pre { margin: 0; } .highlight .gh { color: #999999; } .highlight .sr { color: #f6aa11; } .highlight .go { color: #888888; } .highlight .gp { color: #555555; } .highlight .gs { } .highlight .gu { color: #aaaaaa; } .highlight .nb { color: #f6aa11; } .highlight .cm { color: #75715e; } .highlight .cp { color: #75715e; } .highlight .c1 { color: #75715e; } .highlight .cs { color: #75715e; } .highlight .c, .highlight .cd { color: #75715e; } .highlight .err { color: #960050; } .highlight .gr { color: #960050; } .highlight .gt { color: #960050; } .highlight .gd { color: #49483e; } .highlight .gi { color: #49483e; } .highlight .ge { color: #49483e; } .highlight .kc { color: #66d9ef; } .highlight .kd { color: #66d9ef; } .highlight .kr { color: #66d9ef; } .highlight .no { color: #66d9ef; } .highlight .kt { color: #66d9ef; } .highlight .mf { color: #ae81ff; } .highlight .mh { color: #ae81ff; } .highlight .il { color: #ae81ff; } .highlight .mi { color: #ae81ff; } .highlight .mo { color: #ae81ff; } .highlight .m, .highlight .mb, .highlight .mx { color: #ae81ff; } .highlight .sc { color: #ae81ff; } .highlight .se { color: #ae81ff; } .highlight .ss { color: #ae81ff; } .highlight .sd { color: #e6db74; } .highlight .s2 { color: #e6db74; } .highlight .sb { color: #e6db74; } .highlight .sh { color: #e6db74; } .highlight .si { color: #e6db74; } .highlight .sx { color: #e6db74; } .highlight .s1 { color: #e6db74; } .highlight .s { color: #e6db74; } .highlight .na { color: #a6e22e; } .highlight .nc { color: #a6e22e; } .highlight .nd { color: #a6e22e; } .highlight .ne { color: #a6e22e; } .highlight .nf { color: #a6e22e; } .highlight .vc { color: #ffffff; } .highlight .nn { color: #ffffff; } .highlight .nl { color: #ffffff; } .highlight .ni { color: #ffffff; } .highlight .bp { color: #ffffff; } .highlight .vg { color: #ffffff; } .highlight .vi { color: #ffffff; } .highlight .nv { color: #ffffff; } .highlight .w { color: #ffffff; } .highlight { color: #ffffff; } .highlight .n, .highlight .py, .highlight .nx { color: #ffffff; } .highlight .ow { color: #f92672; } .highlight .nt { color: #f92672; } .highlight .k, .highlight .kv { color: #f92672; } .highlight .kn { color: #f92672; } .highlight .kp { color: #f92672; } .highlight .o { color: #f92672; } </style> <link href="https://userflow.com/images/favicon.png" rel="icon" type="image/png" /> <link href="https://userflow-assets.storage.googleapis.com/assets/doc-pages/stylesheets/screen-f2ba7e1e.css" rel="stylesheet" media="screen" /> <link href="https://userflow-assets.storage.googleapis.com/assets/doc-pages/stylesheets/print-8d191eb3.css" rel="stylesheet" media="print" /> <script src="https://userflow-assets.storage.googleapis.com/assets/doc-pages/javascripts/all-18b97498.js"></script> <script type="text/javascript" id="hs-script-loader" async defer src="//js.hs-scripts.com/9255119.js"></script> </head> <body class="rest-api-docs" data-languages="[]"> <a href="#" id="nav-button"> <span> NAV <img src="https://userflow-assets.storage.googleapis.com/assets/doc-pages/images/navbar-cad8cdcb.png" alt="Navbar" /> </span> </a> <div class="toc-wrapper"> <img src="https://userflow-assets.storage.googleapis.com/assets/doc-pages/images/logo-6281c13f.svg" class="logo" alt="Logo" /> <div class="search"> <input type="text" class="search" id="input-search" placeholder="Search"> </div> <ul class="search-results"></ul> <ul id="toc" class="toc-list-h1"> <li> <a href="#userflow-api-reference" class="toc-h1 toc-link" data-title="Userflow API Reference"> Userflow API Reference </a> </li> <li> <a href="#quick-links" class="toc-h1 toc-link" data-title="Quick links"> Quick links </a> </li> <li> <a href="#authentication" class="toc-h1 toc-link" data-title="Authentication"> Authentication </a> </li> <li> <a href="#versioning" class="toc-h1 toc-link" data-title="Versioning"> Versioning </a> </li> <li> <a href="#rate-limits" class="toc-h1 toc-link" data-title="Rate limits"> Rate limits </a> </li> <li> <a href="#errors" class="toc-h1 toc-link" data-title="Errors"> Errors </a> <ul class="toc-list-h2"> <li> <a href="#http-status-codes" class="toc-h2 toc-link" data-title="HTTP status codes">HTTP status codes</a> </li> <li> <a href="#error-responses" class="toc-h2 toc-link" data-title="Error responses">Error responses</a> </li> </ul> </li> <li> <a href="#pagination" class="toc-h1 toc-link" data-title="Pagination"> Pagination </a> <ul class="toc-list-h2"> <li> <a href="#pagination-query-parameters" class="toc-h2 toc-link" data-title="Pagination query parameters">Pagination query parameters</a> </li> <li> <a href="#the-list-object" class="toc-h2 toc-link" data-title="The list object">The list object</a> </li> </ul> </li> <li> <a href="#ordering" class="toc-h1 toc-link" data-title="Ordering"> Ordering </a> </li> <li> <a href="#expanding-objects" class="toc-h1 toc-link" data-title="Expanding objects"> Expanding objects </a> </li> <li> <a href="#attributes" class="toc-h1 toc-link" data-title="Attributes"> Attributes </a> <ul class="toc-list-h2"> <li> <a href="#attribute-naming" class="toc-h2 toc-link" data-title="Attribute naming">Attribute naming</a> </li> <li> <a href="#attribute-data-types" class="toc-h2 toc-link" data-title="Attribute data types">Attribute data types</a> </li> <li> <a href="#attribute-values-and-operations" class="toc-h2 toc-link" data-title="Attribute values and operations">Attribute values and operations</a> </li> </ul> </li> <li> <a href="#condition-filtering" class="toc-h1 toc-link" data-title="Condition filtering"> Condition filtering </a> <ul class="toc-list-h2"> <li> <a href="#and-and-clause" class="toc-h2 toc-link" data-title="and - AND clause">and - AND clause</a> </li> <li> <a href="#between-is-between" class="toc-h2 toc-link" data-title="between - Is between">between - Is between</a> </li> <li> <a href="#contains-contains" class="toc-h2 toc-link" data-title="contains - Contains">contains - Contains</a> </li> <li> <a href="#empty-is-empty" class="toc-h2 toc-link" data-title="empty - Is empty">empty - Is empty</a> </li> <li> <a href="#ends_with-ends-with" class="toc-h2 toc-link" data-title="ends_with - Ends with">ends_with - Ends with</a> </li> <li> <a href="#eq-equals-is" class="toc-h2 toc-link" data-title="eq - Equals / is">eq - Equals / is</a> </li> <li> <a href="#excludes_all-does-not-include-all-of" class="toc-h2 toc-link" data-title="excludes_all - Does not include all of">excludes_all - Does not include all of</a> </li> <li> <a href="#excludes_any-does-not-include-at-least-one-of" class="toc-h2 toc-link" data-title="excludes_any - Does not include at least one of">excludes_any - Does not include at least one of</a> </li> <li> <a href="#false-is-false" class="toc-h2 toc-link" data-title="false - Is false">false - Is false</a> </li> <li> <a href="#gt-is-greater-than" class="toc-h2 toc-link" data-title="gt - Is greater than">gt - Is greater than</a> </li> <li> <a href="#gte-is-greater-than-or-equal-to" class="toc-h2 toc-link" data-title="gte - Is greater than or equal to">gte - Is greater than or equal to</a> </li> <li> <a href="#includes_all-includes-all-of" class="toc-h2 toc-link" data-title="includes_all - Includes all of">includes_all - Includes all of</a> </li> <li> <a href="#includes_any-includes-at-least-one-of" class="toc-h2 toc-link" data-title="includes_any - Includes at least one of">includes_any - Includes at least one of</a> </li> <li> <a href="#lt-is-less-than" class="toc-h2 toc-link" data-title="lt - Is less than">lt - Is less than</a> </li> <li> <a href="#lte-is-less-than-or-equal-to" class="toc-h2 toc-link" data-title="lte - Is less than or equal to">lte - Is less than or equal to</a> </li> <li> <a href="#ne-is-not-does-not-equal" class="toc-h2 toc-link" data-title="ne - Is not / does not equal">ne - Is not / does not equal</a> </li> <li> <a href="#not_contains-does-not-contain" class="toc-h2 toc-link" data-title="not_contains - Does not contain">not_contains - Does not contain</a> </li> <li> <a href="#not_empty-has-any-value-is-not-empty" class="toc-h2 toc-link" data-title="not_empty - Has any value / is not empty">not_empty - Has any value / is not empty</a> </li> <li> <a href="#or-or-clause" class="toc-h2 toc-link" data-title="or - OR clause">or - OR clause</a> </li> <li> <a href="#starts_with-starts-with" class="toc-h2 toc-link" data-title="starts_with - Starts with">starts_with - Starts with</a> </li> <li> <a href="#true-is-true" class="toc-h2 toc-link" data-title="true - Is true">true - Is true</a> </li> </ul> </li> <li class="toc-group-header">Resources</li> <li> <a href="#users" class="toc-h1 toc-link" data-title="Users"> Users </a> <ul class="toc-list-h2"> <li> <a href="#the-user-object" class="toc-h2 toc-link" data-title="The user object">The user object</a> </li> <li> <a href="#create-or-update-a-user" class="toc-h2 toc-link" data-title="Create or update a user">Create or update a user</a> </li> <li> <a href="#get-a-user" class="toc-h2 toc-link" data-title="Get a user">Get a user</a> </li> <li> <a href="#delete-a-user" class="toc-h2 toc-link" data-title="Delete a user">Delete a user</a> </li> <li> <a href="#list-users" class="toc-h2 toc-link" data-title="List users">List users</a> </li> </ul> </li> <li> <a href="#groups-companies" class="toc-h1 toc-link" data-title="Groups/companies"> Groups/companies </a> <ul class="toc-list-h2"> <li> <a href="#the-group-object" class="toc-h2 toc-link" data-title="The group object">The group object</a> </li> <li> <a href="#create-or-update-a-group" class="toc-h2 toc-link" data-title="Create or update a group">Create or update a group</a> </li> <li> <a href="#get-a-group" class="toc-h2 toc-link" data-title="Get a group">Get a group</a> </li> <li> <a href="#delete-a-group" class="toc-h2 toc-link" data-title="Delete a group">Delete a group</a> </li> <li> <a href="#list-groups" class="toc-h2 toc-link" data-title="List groups">List groups</a> </li> </ul> </li> <li> <a href="#group-memberships" class="toc-h1 toc-link" data-title="Group memberships"> Group memberships </a> <ul class="toc-list-h2"> <li> <a href="#the-group-membership-object" class="toc-h2 toc-link" data-title="The group membership object">The group membership object</a> </li> <li> <a href="#create-or-update-a-group-membership" class="toc-h2 toc-link" data-title="Create or update a group membership">Create or update a group membership</a> </li> <li> <a href="#remove-a-user-from-a-group" class="toc-h2 toc-link" data-title="Remove a user from a group">Remove a user from a group</a> </li> <li> <a href="#list-group-memberships" class="toc-h2 toc-link" data-title="List group memberships">List group memberships</a> </li> </ul> </li> <li> <a href="#events" class="toc-h1 toc-link" data-title="Events"> Events </a> <ul class="toc-list-h2"> <li> <a href="#the-event-object" class="toc-h2 toc-link" data-title="The event object">The event object</a> </li> <li> <a href="#track-an-event" class="toc-h2 toc-link" data-title="Track an event">Track an event</a> </li> </ul> </li> <li> <a href="#content" class="toc-h1 toc-link" data-title="Content"> Content </a> <ul class="toc-list-h2"> <li> <a href="#the-content-object" class="toc-h2 toc-link" data-title="The content object">The content object</a> </li> <li> <a href="#get-a-content-object" class="toc-h2 toc-link" data-title="Get a content object">Get a content object</a> </li> <li> <a href="#list-content" class="toc-h2 toc-link" data-title="List content">List content</a> </li> </ul> </li> <li> <a href="#content-versions" class="toc-h1 toc-link" data-title="Content versions"> Content versions </a> <ul class="toc-list-h2"> <li> <a href="#the-content-version-object" class="toc-h2 toc-link" data-title="The content version object">The content version object</a> </li> <li> <a href="#the-question-object" class="toc-h2 toc-link" data-title="The question object">The question object</a> </li> <li> <a href="#the-checklist-task-object" class="toc-h2 toc-link" data-title="The checklist task object">The checklist task object</a> </li> <li> <a href="#get-a-content-version" class="toc-h2 toc-link" data-title="Get a content version">Get a content version</a> </li> <li> <a href="#list-content-versions" class="toc-h2 toc-link" data-title="List content versions">List content versions</a> </li> </ul> </li> <li> <a href="#content-sessions" class="toc-h1 toc-link" data-title="Content sessions"> Content sessions </a> <ul class="toc-list-h2"> <li> <a href="#the-content-session-object" class="toc-h2 toc-link" data-title="The content session object">The content session object</a> </li> <li> <a href="#the-content-session-answer-object" class="toc-h2 toc-link" data-title="The content session answer object">The content session answer object</a> </li> <li> <a href="#get-a-content-session" class="toc-h2 toc-link" data-title="Get a content session">Get a content session</a> </li> <li> <a href="#list-content-sessions" class="toc-h2 toc-link" data-title="List content sessions">List content sessions</a> </li> </ul> </li> <li> <a href="#attribute-definitions" class="toc-h1 toc-link" data-title="Attribute definitions"> Attribute definitions </a> <ul class="toc-list-h2"> <li> <a href="#the-attribute-definition-object" class="toc-h2 toc-link" data-title="The attribute definition object">The attribute definition object</a> </li> <li> <a href="#list-attribute-definitions" class="toc-h2 toc-link" data-title="List attribute definitions">List attribute definitions</a> </li> </ul> </li> <li> <a href="#event-definitions" class="toc-h1 toc-link" data-title="Event definitions"> Event definitions </a> <ul class="toc-list-h2"> <li> <a href="#the-event-definition-object" class="toc-h2 toc-link" data-title="The event definition object">The event definition object</a> </li> <li> <a href="#event-naming" class="toc-h2 toc-link" data-title="Event naming">Event naming</a> </li> <li> <a href="#list-event-definitions" class="toc-h2 toc-link" data-title="List event definitions">List event definitions</a> </li> </ul> </li> <li> <a href="#webhook-subscriptions" class="toc-h1 toc-link" data-title="Webhook subscriptions"> Webhook subscriptions </a> <ul class="toc-list-h2"> <li> <a href="#the-webhook-subscription-object" class="toc-h2 toc-link" data-title="The webhook subscription object">The webhook subscription object</a> </li> <li> <a href="#the-webhook-notification-object" class="toc-h2 toc-link" data-title="The webhook notification object">The webhook notification object</a> </li> <li> <a href="#webhook-topics" class="toc-h2 toc-link" data-title="Webhook topics">Webhook topics</a> </li> <li> <a href="#receiving-webhooks" class="toc-h2 toc-link" data-title="Receiving webhooks">Receiving webhooks</a> </li> <li> <a href="#webhook-signatures" class="toc-h2 toc-link" data-title="Webhook signatures">Webhook signatures</a> </li> <li> <a href="#create-a-webhook-subscription" class="toc-h2 toc-link" data-title="Create a webhook subscription">Create a webhook subscription</a> </li> <li> <a href="#get-a-webhook-subscription" class="toc-h2 toc-link" data-title="Get a webhook subscription">Get a webhook subscription</a> </li> <li> <a href="#update-a-webhook-subscription" class="toc-h2 toc-link" data-title="Update a webhook subscription">Update a webhook subscription</a> </li> <li> <a href="#delete-a-webhook-subscription" class="toc-h2 toc-link" data-title="Delete a webhook subscription">Delete a webhook subscription</a> </li> <li> <a href="#list-webhook-subscriptions" class="toc-h2 toc-link" data-title="List webhook subscriptions">List webhook subscriptions</a> </li> </ul> </li> </ul> <ul class="toc-footer"> <li><a href='/docs/dev'>Developer Docs Home</a></li> <li><a href='/docs/dev/userflow-js'>Userflow.js</a></li> </ul> </div> <div class="page-wrapper"> <div class="dark-box"></div> <div class="content"> <h1 id='userflow-api-reference'>Userflow API Reference</h1> <blockquote> <p>Userflow API endpoint:</p> </blockquote> <pre class="highlight plaintext"><code>https://api.userflow.com </code></pre> <p>With the <a href="/">Userflow</a> REST API you can synchronize your user data with Userflow, and track events directly from your back-end application.</p> <p>The API is based on <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST</a>. Its URLs are resource-oriented and it uses the standard HTTP verbs (<code>GET</code>, <code>POST</code> etc.). It receives and responds with JSON. It responds with standard HTTP response codes.</p> <p><a href="https://twitter.com/getuserflow">Follow us on Twitter</a> for API announcements.</p> <h1 id='quick-links'>Quick links</h1> <p>Quick access to endpoints that you'll probably need:</p> <ul> <li><a href="#create-or-update-a-user">Create or update a user</a></li> <li><a href="#create-or-update-a-group">Create or update a group/company</a></li> <li><a href="#track-an-event">Track an event</a></li> </ul> <h1 id='authentication'>Authentication</h1> <blockquote> <p>Include your API key in the Authorization header prefixed with "Bearer ":</p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/users <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> </code></pre> <blockquote> <p>Example:</p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/users <span class="se">\</span> -H <span class="s1">'Authorization: Bearer ak_2snys2ycbvetjeivbzs7m7btfm'</span> </code></pre> <p>You use API keys to authenticate your API requests. You can view and create API keys in the Userflow web app under <a href="https://userflow.com/app/_/settings/api">Settings -> API</a>. Note that if you have multiple environments (e.g. Production and Staging) that each environment has separate API keys, and that an API key only authorize access to its environment.</p> <p>API keys grant access to a whole environment in your account! Make sure to keep them safe and secret. Do not put them in your GitHub repo or in your client-side code.</p> <p>All API requests must be made over HTTPS. Calls made over plain HTTP will fail. API requests without authentication will also fail.</p> <h1 id='versioning'>Versioning</h1> <blockquote> <p>Override API version (recommended!):</p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/users <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <p>When we make backwards-incompatible changes to the API, we release new, dated versions. The current (and so far only) version is <code>2020-01-03</code>.</p> <p>All requests will default to using the latest API version, unless you explicitly override the API version with the <code>Userflow-Version</code> header.</p> <p>We therefore <strong>strongly recommend</strong> that you specify your desired version to make sure your integration won't break in the future.</p> <h1 id='rate-limits'>Rate limits</h1> <p>The API employs 2 safeguards against bursts of incoming traffic to help maximize its stability:</p> <ul> <li>A <strong>rate limiter</strong> that limits the number of requests per Userflow account per minute. Your account's limit depends on your plan. See <a href="https://userflow.com/pricing">Pricing</a>. If you exceed this limit, you may receive error responses with HTTP status code <code>429 Too Many Requests</code>.</li> <li>A <strong>concurrency limiter</strong> that limits the number of requests that are active at any given time. If the API is at high capacity, it may delay responding to some requests. If requests are queued for more than 15 seconds, you may receive error responses with HTTP status code <code>503 Service Unavailable</code>. Problems with concurrency limiting should be very rare. We strive to have enough capacity at all times to avoid (or at least minimize) queuing and never timing out.</li> </ul> <h1 id='errors'>Errors</h1><h2 id='http-status-codes'>HTTP status codes</h2> <p>The API responds with HTTP status codes in the 2xx range when requests are successful. If a request is invalid due to information provided (e.g. a missing parameter, or), it'll respond with 4xx codes. If Userflow experiences an internal error, it'll respond with 5xx errors.</p> <table><thead> <tr> <th>Code</th> <th>Meaning</th> </tr> </thead><tbody> <tr> <td>200</td> <td><strong>OK</strong> - Request was successful</td> </tr> <tr> <td>400</td> <td><strong>Bad Request</strong> - Invalid query parameters or JSON body. Check the error response for details on how to fix.</td> </tr> <tr> <td>401</td> <td><strong>Unauthorized</strong> - Missing or invalid API key.</td> </tr> <tr> <td>404</td> <td><strong>Not Found</strong> - Unrecognized URL.</td> </tr> <tr> <td>405</td> <td><strong>Method Not Allowed</strong> - The used HTTP method (e.g. <code>GET</code>) is not allowed for the given URL.</td> </tr> <tr> <td>406</td> <td><strong>Not Acceptable</strong> - You requested a format that isn't JSON.</td> </tr> <tr> <td>415</td> <td><strong>Unsupported Media Type</strong> - You probably forgot to add <code>Content-Type: application/json</code> to a <code>POST</code> request.</td> </tr> <tr> <td>429</td> <td><strong>Too Many Requests</strong> - You have sent too many requests, too quickly, and are being rate limited. See <a href="#rate-limits">Rate limits</a>.</td> </tr> <tr> <td>500</td> <td><strong>Internal Server Error</strong> - Something went wrong on Userflow's end. Consider retrying the request, or reach out to Userflow for help.</td> </tr> <tr> <td>503</td> <td><strong>Internal Server Error</strong> - Service Unavailable - We're temporarily offline for maintenance. Please try again later.</td> </tr> </tbody></table> <h2 id='error-responses'>Error responses</h2> <blockquote> <p>Example error response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"error"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"code"</span><span class="p">:</span><span class="w"> </span><span class="s2">"invalid_api_key"</span><span class="p">,</span><span class="w"> </span><span class="s2">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Invalid API key provided: ..."</span><span class="p">,</span><span class="w"> </span><span class="s2">"doc_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://userflow.com/docs/api"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Error responses contains an <code>error</code> object with the following properties:</p> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>code</code></td> <td><em>String</em> - Machine-readable error code.</td> </tr> <tr> <td><code>message</code></td> <td><em>String</em> - Human-readable explanation of what went wrong.</td> </tr> <tr> <td><code>doc_url</code></td> <td><em>String</em> - URL to the Userflow API docs.</td> </tr> <tr> <td><code>request_id</code></td> <td><em>String</em> - Userflow assigns all requests an ID. When you report issues to us, including this request ID will make it easier for us to see what happened.</td> </tr> </tbody></table> <h1 id='pagination'>Pagination</h1> <p>All top-level API resources that support listing (such as <a href="#list-users">listing users</a>) use the same format for pagination and the same response object.</p> <h2 id='pagination-query-parameters'>Pagination query parameters</h2> <p>Listing uses cursor-based pagination through 2 query parameters: <code>limit</code> and <code>starting_after</code>.</p> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>limit</code></td> <td><em>Number</em> - Tells Userflow how many items to respond with. Must be between 1 and 100. Defaults to 10.</td> </tr> <tr> <td><code>starting_after</code></td> <td><em>String</em> - Tells Userflow to respond with items in the list <em>immediately after and not including</em> the object with the given id. If you want the next page, use the id of the last item in the previous request. It's often easiest to use the <a href="#the-list-object">list object's</a> <code>next_page_url</code> field though. If <code>starting_after</code> is not set, Userflow will return items from the beginning of the list.</td> </tr> </tbody></table> <h2 id='the-list-object'>The list object</h2> <blockquote> <p>Example list object (from <code>GET /users</code>):</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"list"</span><span class="p">,</span><span class="w"> </span><span class="s2">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"user"</span><span class="p">,</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"10"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"user"</span><span class="p">,</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">],</span><span class="w"> </span><span class="s2">"has_more"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="s2">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/users"</span><span class="p">,</span><span class="w"> </span><span class="s2">"next_page_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/users?starting_after=10"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>All list endpoints returns an object with the following keys:</p> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>object</code></td> <td><em>String</em> - Represents the object's type. Always <code>list</code>.</td> </tr> <tr> <td><code>data</code></td> <td><em>Array</em> - An array containing the actual response objects (e.g. users). No more than <code>limit</code> elements will be included.</td> </tr> <tr> <td><code>has_more</code></td> <td><em>Boolean</em> - <code>true</code> if there are more items in the next page, <code>false</code> if this is the last page.</td> </tr> <tr> <td><code>url</code></td> <td><em>String</em> - The URL for this list. This will include any pagination parameters, filters or order-by parameters.</td> </tr> <tr> <td><code>next_page_url</code></td> <td><em>String</em> - URL to fetch the next page from. Will always be set, even if <code>has_more</code> is <code>false</code>. This is because there may not <em>currently</em> be more items in the list, but some clients may still want to know how to fetch the next page <em>if</em> more items were to arrive later.</td> </tr> </tbody></table> <h1 id='ordering'>Ordering</h1> <blockquote> <p>Order by single field:</p> </blockquote> <pre class="highlight plaintext"><code>GET /users?order_by=attributes.name </code></pre> <blockquote> <p>Order by multiple fields:</p> </blockquote> <pre class="highlight plaintext"><code>GET /users?order_by[]=attributes.name&order_by[]=created_at </code></pre> <blockquote> <p>Use descending order:</p> </blockquote> <pre class="highlight plaintext"><code>GET /users?order_by=-created_at </code></pre> <p>Some top-level API resources that support listing (such as <a href="#list-users">listing users</a>) can be ordered by one or more fields using a <code>sort_by</code> query parameter. Each resource will list which fields it can be ordered by.</p> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>order_by</code></td> <td><em>String or array of strings</em> - A single field or a an array of fields to order by. If you include multiple fields, the list will be sorted by the first element first, then the second, and so on. Each field is sorted in ascending order, unless you prefix it with a <code>-</code> (hyphen), in which case it'll be sorted in descending order.</td> </tr> </tbody></table> <h1 id='expanding-objects'>Expanding objects</h1> <blockquote> <p>Get a user with all their memberships and groups/companies:</p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/users/1?expand<span class="o">=</span>memberships.group <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"user"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Maxie Kris"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"memberships"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"e9b32bd0-63cb-415e-9c4f-477c85b92f97"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"group_membership"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"role"</span><span class="p">:</span><span class="w"> </span><span class="s2">"admin"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"group"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ab82c312-b3a4-4feb-870c-53dd336f955e"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"group"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Acme Inc."</span><span class="p">,</span><span class="w"> </span><span class="s2">"billing_plan"</span><span class="p">:</span><span class="w"> </span><span class="s2">"plus"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"group_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ab82c312-b3a4-4feb-870c-53dd336f955e"</span><span class="p">,</span><span class="w"> </span><span class="s2">"user"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"user_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">]</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>You can ask for objects or lists to be expanded in responses from the API using the <code>expand</code> query parameter. For example, an event object has a <code>user_id</code>, which simply contains the string ID of the user the event is related to. By adding <code>?expand=user</code> to the request URL, the API will respond with an extra <code>user</code> key which contains the full user object.</p> <p>Expansion also works with has-many relationships, such as a user's list of memberships. By default, the <code>memberships</code> key will be <code>null</code> (not expanded). If you add <code>?expand=memberships</code>, the API will respond with an array of all the user's memberships.</p> <p>You can expand recursively by specifying nested fields separated with a dot (<code>.</code>). Example to get memberships and their groups: <code>?expand=memberships.group</code>. You can expand to a maximum of 4 levels deep.</p> <p>You can use the <code>expand</code> parameter on any endpoint which returns expandable fields, including list, create, and update endpoints.</p> <p>You can expand multiple objects at once by adding multiple paths in the <code>expand</code> array. Example: <code>?expand[]=user&expand[]=group</code>.</p> <h1 id='attributes'>Attributes</h1> <blockquote> <p>Example user object with attributes:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2a845972-4cde-4cb4-ba14-5cb2fc15ec4c"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"user"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"email"</span><span class="p">:</span><span class="w"> </span><span class="s2">"annabelle@example.com"</span><span class="p">,</span><span class="w"> </span><span class="s2">"email_verified"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Annabelle Terry"</span><span class="p">,</span><span class="w"> </span><span class="s2">"project_count"</span><span class="p">:</span><span class="w"> </span><span class="mi">17</span><span class="p">,</span><span class="w"> </span><span class="s2">"signed_up_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-09-29T12:34:56.000+00:00"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Some objects, such as users, groups and events, can hold custom attributes in the free-form <code>attributes</code> dictionaries.</p> <h2 id='attribute-naming'>Attribute naming</h2> <p>Attribute names (the keys in <code>attributes</code> dictionaries) can only consist of a-z, A-Z, 0-9, underscores, dashes and spaces.</p> <p>We recommend using <code>snake_case</code> everywhere though.</p> <p>Attributes' human-friendly display names (e.g. "Signed Up" for <code>signed_up_at</code>) can also be configured in the Userflow UI.</p> <h2 id='attribute-data-types'>Attribute data types</h2> <p>We support the following attribute data types:</p> <table><thead> <tr> <th>Name</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>string</code></td> <td>Represents a string.</td> </tr> <tr> <td><code>number</code></td> <td>Represents a number (supports both integers and floating point numbers).</td> </tr> <tr> <td><code>boolean</code></td> <td>Represents either <code>true</code> or <code>false</code>.</td> </tr> <tr> <td><code>datetime</code></td> <td>Represents a point in time, always stored as ISO 8601 in UTC.</td> </tr> <tr> <td><code>list</code></td> <td>Represents a list of strings.</td> </tr> </tbody></table> <h2 id='attribute-values-and-operations'>Attribute values and operations</h2> <blockquote> <p>Explicitly specify data type:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2a845972-4cde-4cb4-ba14-5cb2fc15ec4c"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"phone"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="s2">"set"</span><span class="p">:</span><span class="w"> </span><span class="mi">12345678</span><span class="p">,</span><span class="w"> </span><span class="s2">"data_type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <blockquote> <p>Set attribute, unless it has already been set:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2a845972-4cde-4cb4-ba14-5cb2fc15ec4c"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"coupon_code"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="s2">"set_once"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xyz123"</span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <blockquote> <p>Increment attribute:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2a845972-4cde-4cb4-ba14-5cb2fc15ec4c"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"widget_count"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="s2">"add"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">},</span><span class="w"> </span><span class="s2">"total_revenue"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="s2">"add"</span><span class="p">:</span><span class="w"> </span><span class="mf">1234.56</span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <blockquote> <p>Decrement attribute:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2a845972-4cde-4cb4-ba14-5cb2fc15ec4c"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"days_left"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="s2">"subtract"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <blockquote> <p>Append a single value to a list:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2a845972-4cde-4cb4-ba14-5cb2fc15ec4c"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"foods"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="s2">"append"</span><span class="p">:</span><span class="w"> </span><span class="s2">"apple"</span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <blockquote> <p>Append a multiple values to a list:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2a845972-4cde-4cb4-ba14-5cb2fc15ec4c"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"foods"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="s2">"append"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"apple"</span><span class="p">,</span><span class="w"> </span><span class="s2">"banana"</span><span class="p">]}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <blockquote> <p>Prepend values to a list:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2a845972-4cde-4cb4-ba14-5cb2fc15ec4c"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"foods"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="s2">"prepend"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"apple"</span><span class="p">,</span><span class="w"> </span><span class="s2">"banana"</span><span class="p">]}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <blockquote> <p>Remove values from a list:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2a845972-4cde-4cb4-ba14-5cb2fc15ec4c"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"foods"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="s2">"remove"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"apple"</span><span class="p">,</span><span class="w"> </span><span class="s2">"banana"</span><span class="p">]}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <blockquote> <p>Unset attribute:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2a845972-4cde-4cb4-ba14-5cb2fc15ec4c"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"remove_me"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>When updating objects with attributes, the values in the <code>attributes</code> dictionary can be literal values (string, boolean, number), which just sets the attributes to the given values.</p> <p>If an attribute value is <code>null</code>, the attribute will be unset/removed from the user.</p> <p>You can also specify an operation object instead of a literal value. This operation object can contain the following keys (note that exactly one of <code>set</code>, <code>set_once</code>, <code>add</code>, <code>subtract</code>, <code>append</code>, <code>prepend</code> or <code>remove</code> must be set):</p> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>set</code></td> <td><em>String/number/boolean</em> - Sets the attribute to this value. This is the same as using literal values, except this way you can explicitly set the <code>data_type</code>, too.</td> </tr> <tr> <td><code>set_once</code></td> <td><em>String/number/boolean</em> - Sets the attribute to this value, but only if the user doesn't already have a value for this attribute.</td> </tr> <tr> <td><code>add</code></td> <td><em>Number</em> - Adds this value to the attribute's current value. If the user does not have the attribute yet, the given number will be added to <code>0</code>. Only works on <code>number</code> attributes.</td> </tr> <tr> <td><code>subtract</code></td> <td><em>Number</em> - Same as <code>add</code>, but subtracts the given number instead. To subtract, you either supply a negative number to <code>add</code>, or a positive number to <code>subtract</code>.</td> </tr> <tr> <td><code>append</code></td> <td><em>String/list of strings</em> - Adds one or more values to the end of a <code>list</code> type attribute. If the user's attribute value was not set before, it will be initialized to an empty list before the values are appended. Any values already present in the user's attribute value will be ignored (no duplicates are inserted).</td> </tr> <tr> <td><code>prepend</code></td> <td><em>String/list of strings</em> - Like <code>append</code>, but inserts the values at the beginning of the list.</td> </tr> <tr> <td><code>remove</code></td> <td><em>String/list of strings</em> - Removes one or more values from a <code>list</code> type attribute. If the user's attribute value was not set before, it will be set to an empty list.</td> </tr> <tr> <td><code>data_type</code></td> <td><em>String</em> - Explicitly tells Userflow what data type to use. See <a href="#attribute-data-types">Attribute data types</a> for possible values. You usually don't have to set this, as Userflow will infer the right data type depending on the values you supply.</td> </tr> </tbody></table> <h1 id='condition-filtering'>Condition filtering</h1> <blockquote> <p>Using the <code>condition</code> parameter when listing users:</p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/users?condition<span class="o">=</span>%7B%22type%22%3A%22attribute%22%2C%22attribute_name%22%3A%22plan%22%2C%22operator%22%3A%22eq%22%2C%22value%22%3A%22Pro%22%7D <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <blockquote> <p>Simple condition filtering on a user attribute:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"experience_level"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"eq"</span><span class="p">,</span><span class="w"> </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Expert"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <blockquote> <p>Simple condition filtering on a group attribute:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"group/plan"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"eq"</span><span class="p">,</span><span class="w"> </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Pro"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <blockquote> <p>Advanced condition matching users who are both on the Pro plan and has created at least 10 widgets:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"clause"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"and"</span><span class="p">,</span><span class="w"> </span><span class="s2">"conditions"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"plan"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"eq"</span><span class="p">,</span><span class="w"> </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Pro"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"widget_count"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"gte"</span><span class="p">,</span><span class="w"> </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">]</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>When <a href="#list-users">listing users</a> and <a href="#list-groups">listing groups</a>, you can provide a <code>?condition</code> query parameter to filter the list based on attributes.</p> <p>The <code>condition</code> parameter must be a JSON-formatted string.</p> <p>You can perform <code>AND</code> and <code>OR</code> logic using multiple conditions combined in a <code>conditions</code> list.</p> <p>When referring to attribute names in <code>"type": "attribute"</code> conditions, the <code>attribute_name</code> defaults to refer to a user attribute, e.g. <code>experience_level</code>. If you want to refer to a group attribute, such as <code>plan</code>, then you must prefix it like <code>group/plan</code>. If you want to refer to a membership attribute, such as <code>role</code>, then you must prefix it like <code>group_membership/role</code>.</p> <p>Note that condition filtering is intended to find a small number of matching users. If the condition matches more than 10,000 records, the request will be rejected.</p> <p>We support the following types of conditions.</p> <h2 id='and-and-clause'>and - AND clause</h2><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"clause"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"and"</span><span class="p">,</span><span class="w"> </span><span class="s2">"conditions"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="err">...condition</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="err">...condition</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">]</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Used to combine multiple child conditions with <code>AND</code>.</p> <p>True if all of the child <code>conditions</code> are true.</p> <h2 id='between-is-between'>between - Is between</h2><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my_attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"between"</span><span class="p">,</span><span class="w"> </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="mi">10</span><span class="p">,</span><span class="w"> </span><span class="s2">"value2"</span><span class="p">:</span><span class="w"> </span><span class="mi">20</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>True if the given number attribute is between <code>value</code> and <code>value2</code> (both inclusive).</p> <h2 id='contains-contains'>contains - Contains</h2><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my_attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"contains"</span><span class="p">,</span><span class="w"> </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my value"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>True if the given string attribute contains the string <code>value</code>.</p> <h2 id='empty-is-empty'>empty - Is empty</h2><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my_attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"empty"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>True if the given attribute is either not set, null, an empty string or an empty list.</p> <h2 id='ends_with-ends-with'>ends_with - Ends with</h2><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my_attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ends_with"</span><span class="p">,</span><span class="w"> </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my value"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>True if the given string attribute ends with <code>value</code>.</p> <h2 id='eq-equals-is'>eq - Equals / is</h2><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my_attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"eq"</span><span class="p">,</span><span class="w"> </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my value"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>True if the given attribute equals <code>value</code>.</p> <h2 id='excludes_all-does-not-include-all-of'>excludes_all - Does not include all of</h2><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my_attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"excludes_all"</span><span class="p">,</span><span class="w"> </span><span class="s2">"values"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"apple"</span><span class="p">,</span><span class="w"> </span><span class="s2">"banana"</span><span class="p">]</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>True if the given list attribute does not include all of the given <code>values</code> (an array of strings).</p> <h2 id='excludes_any-does-not-include-at-least-one-of'>excludes_any - Does not include at least one of</h2><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my_attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"excludes_any"</span><span class="p">,</span><span class="w"> </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my value"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>True if the given list attribute does not include at least one of the given <code>values</code> (an array of strings).</p> <h2 id='false-is-false'>false - Is false</h2><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my_attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"false"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>True if the given boolean attribute is <code>false</code>.</p> <h2 id='gt-is-greater-than'>gt - Is greater than</h2><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my_attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"gt"</span><span class="p">,</span><span class="w"> </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="mi">123</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>True if the given number attribute is greater than <code>value</code>.</p> <h2 id='gte-is-greater-than-or-equal-to'>gte - Is greater than or equal to</h2><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my_attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"gte"</span><span class="p">,</span><span class="w"> </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="mi">123</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>True if the given number attribute is greater than <code>value</code>.</p> <h2 id='includes_all-includes-all-of'>includes_all - Includes all of</h2><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my_attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"includes_all"</span><span class="p">,</span><span class="w"> </span><span class="s2">"values"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"apple"</span><span class="p">,</span><span class="w"> </span><span class="s2">"banana"</span><span class="p">]</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>True if the given list attribute includes all of the given <code>values</code> (an array of strings).</p> <h2 id='includes_any-includes-at-least-one-of'>includes_any - Includes at least one of</h2><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my_attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"includes_any"</span><span class="p">,</span><span class="w"> </span><span class="s2">"values"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"apple"</span><span class="p">,</span><span class="w"> </span><span class="s2">"banana"</span><span class="p">]</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>True if the given list attribute includes at least one of the given <code>values</code> (an array of strings).</p> <h2 id='lt-is-less-than'>lt - Is less than</h2><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my_attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"lt"</span><span class="p">,</span><span class="w"> </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="mi">123</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>True if the given number attribute is less than <code>value</code>.</p> <h2 id='lte-is-less-than-or-equal-to'>lte - Is less than or equal to</h2><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my_attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"lte"</span><span class="p">,</span><span class="w"> </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="mi">123</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>True if the given number attribute is less than or equal to <code>value</code>.</p> <h2 id='ne-is-not-does-not-equal'>ne - Is not / does not equal</h2><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my_attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ne"</span><span class="p">,</span><span class="w"> </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my value"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>True if the given attribute does not equal <code>value</code>.</p> <h2 id='not_contains-does-not-contain'>not_contains - Does not contain</h2><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my_attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"not_contains"</span><span class="p">,</span><span class="w"> </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my value"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>True if the given string attribute does not contain <code>value</code>.</p> <h2 id='not_empty-has-any-value-is-not-empty'>not_empty - Has any value / is not empty</h2><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my_attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"not_empty"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>True if the given attribute is set and is neither an empty string, nor null nor an empty list.</p> <h2 id='or-or-clause'>or - OR clause</h2><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"clause"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"or"</span><span class="p">,</span><span class="w"> </span><span class="s2">"conditions"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="err">...condition</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="err">...condition</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">]</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Used to combine multiple child conditions with <code>OR</code>.</p> <p>True if at least one of the child <code>conditions</code> is true.</p> <h2 id='starts_with-starts-with'>starts_with - Starts with</h2><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my_attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"starts_with"</span><span class="p">,</span><span class="w"> </span><span class="s2">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my value"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>True if the given string attribute starts with <code>value</code>.</p> <h2 id='true-is-true'>true - Is true</h2><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attribute_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"my_attribute"</span><span class="p">,</span><span class="w"> </span><span class="s2">"operator"</span><span class="p">:</span><span class="w"> </span><span class="s2">"true"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>True if the given boolean attribute is <code>true</code>.</p> <h1 id='users'>Users</h1> <p>Users are the people using your application. Userflow keeps track of your users, so we can determine which flows to show them, and remember which flows they've already seen.</p> <p>Your application can either register users with Userflow and update their attributes on the client-side using Userflow.js'<a href="/docs/userflow-js#identify"> <code>userflow.identify()</code></a> method, or directly from your back-end using this API.</p> <h2 id='the-user-object'>The user object</h2> <blockquote> <p>Example user object:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"34907ae0-24e0-4261-ac31-3c7299a354c0"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"user"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"email"</span><span class="p">:</span><span class="w"> </span><span class="s2">"annabelle@example.com"</span><span class="p">,</span><span class="w"> </span><span class="s2">"email_verified"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Annabelle Terry"</span><span class="p">,</span><span class="w"> </span><span class="s2">"project_count"</span><span class="p">:</span><span class="w"> </span><span class="mi">17</span><span class="p">,</span><span class="w"> </span><span class="s2">"signed_up_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-09-29T12:34:56.000+00:00"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"groups"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"memberships"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>id</code></td> <td><em>String</em> - Unique identifier for the user. Should match the ID the user has in your database.</td> </tr> <tr> <td><code>object</code></td> <td><em>String</em> - Represents the object's type. Always <code>user</code>.</td> </tr> <tr> <td><code>attributes</code></td> <td><em>Object</em> - A map with all the user's attributes. You can add any attributes you want here.</td> </tr> <tr> <td><code>created_at</code></td> <td><em>String</em> - ISO 8601 date time representing when the user was created with Userflow. Note that this is not the time the user signed up in your app - use an attribute such as <code>signed_up_at</code> in the <code>attributes</code> object for that.</td> </tr> <tr> <td><code>groups</code></td> <td><em>Array of <a href="#the-group-object">group objects</a></em> - A list of all the groups the user is a member of. This field is only useful if you're not interested in membership attributes, in which case you should use <code>memberships</code>. Defaults to <code>null</code>, but can be <a href="#expanding-objects">expanded</a> using <code>?expand=groups</code>.</td> </tr> <tr> <td><code>memberships</code></td> <td><em>Array of <a href="#the-group-membership-object">group membership objects</a></em> - A list of all the user's group memberships. Memberships can hold attributes that describe the user's role for just this group (e.g. their access level). Each membership object will point to an actual <a href="#the-group-object">group object</a>. Defaults to <code>null</code>, but can be <a href="#expanding-objects">expanded</a> using <code>?expand=memberships</code>, or <code>?expand=memberships.group</code> if you want to expand both the user's memberships and each group.</td> </tr> </tbody></table> <h2 id='create-or-update-a-user'>Create or update a user</h2> <blockquote> <p><code>POST /users</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/users <span class="se">\</span> -XPOST <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> <span class="se">\</span> -H <span class="s1">'Content-Type: application/json'</span> <span class="se">\</span> -d <span class="s1">'{ "id": "2a845972-4cde-4cb4-ba14-5cb2fc15ec4c", "attributes": { "name": "Evelyn Reichert", "email": "evelyn@example.com", "signed_up_at": "2022-09-29T12:34:56.000+00:00" } }'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2a845972-4cde-4cb4-ba14-5cb2fc15ec4c"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"user"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"email"</span><span class="p">:</span><span class="w"> </span><span class="s2">"evelyn@example.com"</span><span class="p">,</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Evelyn Reichert"</span><span class="p">,</span><span class="w"> </span><span class="s2">"signed_up_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-09-29T12:34:56.000+00:00"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Creating and updating a user is the same operation. If a user with the same ID doesn't already exist in Userflow, it will be created. If it already exists, the given attributes will be merged into the existing user's attributes.</p> <h4 id='request-body'>Request body</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>id</code>*</td> <td><em>String</em> - Unique identifier for the user. Should match the ID the user has in your database.</td> </tr> <tr> <td><code>attributes</code></td> <td><em>Object</em> - A map with attributes to update for the user. You can add any attributes you want here. Existing attributes not included in the request will not be touched. Attribute values can either be supplied as literal values (string, boolean, number) or as operations (set, set_once, add, subtract). See <a href="#attributes">Attributes</a>.</td> </tr> <tr> <td><code>groups</code>**</td> <td><em>Array of <a href="#the-group-object">group objects</a></em> - A list of groups/companies to update and ensure the user is a member of. This field is simpler to use than <code>memberships</code>, if you don't use membership attributes.</td> </tr> <tr> <td><code>memberships</code>**</td> <td><em>Array of <a href="#the-group-membership-object">group membership objects</a></em> - A list of group/company memberships to create/update for the user. Memberships can hold attributes that describe the user's role for just this group (e.g. their access level). Each membership object must include an embedded <a href="#the-group-object">group object</a> with the group's <code>id</code> as a minimum.</td> </tr> <tr> <td><code>prune_memberships</code></td> <td>Boolean - By default, the API will only update the memberships/groups that's included in the request. Existing memberships that are not included will not be removed, unless you set <code>prune_memberships</code> to <code>true</code>. Only set <code>prune_memberships</code> to <code>true</code>, if the <code>groups</code> or <code>memberships</code> list is set and contains <em>all</em> the groups the user belongs to. When a membership is deleted, the group itself is left intact.</td> </tr> </tbody></table> <p>* Required<br> ** Only one of <code>groups</code> and <code>memberships</code> can be set.</p> <h4 id='response-body'>Response body</h4> <p>Returns the created/updated <a href="#the-user-object">user object</a>.</p> <h3 id='create-or-update-a-user-with-groups'>Create or update a user with groups</h3> <blockquote> <p>Create/update user including groups/companies (not using memberships)</p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/users <span class="se">\</span> -XPOST <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> <span class="se">\</span> -H <span class="s1">'Content-Type: application/json'</span> <span class="se">\</span> -d <span class="s1">'{ "id": "2a845972-4cde-4cb4-ba14-5cb2fc15ec4c", "attributes": { "name": "Evelyn Reichert", }, "groups": [ { "id": "ab82c312-b3a4-4feb-870c-53dd336f955e", "attributes": { "name": "Acme Inc.", "billing_plan": "plus", } } ] }'</span> </code></pre> <p>You can create/update a user and associate it with one or more groups/companies in one go by embedding a list of groups.</p> <p>If you want to assign attributes to the user's membership of the group (e.g. their access level), use the <code>memberships</code> key instead (see next section).</p> <h3 id='create-or-update-a-user-with-memberships'>Create or update a user with memberships</h3> <blockquote> <p>Create/update user including group/company memberships</p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/users <span class="se">\</span> -XPOST <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> <span class="se">\</span> -H <span class="s1">'Content-Type: application/json'</span> <span class="se">\</span> -d <span class="s1">'{ "id": "2a845972-4cde-4cb4-ba14-5cb2fc15ec4c", "attributes": { "name": "Evelyn Reichert", }, "memberships": [ { "attributes": { "role": "admin" }, "group": { "id": "ab82c312-b3a4-4feb-870c-53dd336f955e", "attributes": { "name": "Acme Inc.", "billing_plan": "plus", } } } ] }'</span> </code></pre> <p>You can create/update a user, associate it with one or more groups/companies and assign attributes to the user's membership of each group in one go by embedding a list of memberships.</p> <p>Memberships can hold attributes that describe the user's role for just this group (e.g. their access level).</p> <h2 id='get-a-user'>Get a user</h2> <blockquote> <p><code>GET /users/:user_id</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/users/50c3d110-80f0-47c8-8364-9adfcdb2c9fa <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"50c3d110-80f0-47c8-8364-9adfcdb2c9fa"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"user"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"email"</span><span class="p">:</span><span class="w"> </span><span class="s2">"nathanial@example.com"</span><span class="p">,</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Nathaniel Harvey"</span><span class="p">,</span><span class="w"> </span><span class="s2">"signed_up_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-09-29T12:34:56.000+00:00"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"groups"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"memberships"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Retrieves a user including all their attributes.</p> <h4 id='url-arguments'>URL arguments</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>user_id</code>*</td> <td><em>String</em> - Unique identifier for the user. Should match the ID the user has in your database.</td> </tr> </tbody></table> <p>* Required</p> <h4 id='response-body-2'>Response body</h4> <p>Returns the <a href="#the-user-object">user object</a>, if found. Responds with <code>404 Not Found</code> if not.</p> <h2 id='delete-a-user'>Delete a user</h2> <blockquote> <p><code>DELETE /users/:user_id</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/users/4c20f0fb-a835-4f3c-b726-8c34bf538dcc <span class="se">\</span> -XDELETE <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"4c20f0fb-a835-4f3c-b726-8c34bf538dcc"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"user"</span><span class="p">,</span><span class="w"> </span><span class="s2">"deleted"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Permanently deletes a user including all their attributes, memberships, events and flow history. It cannot be undone. Groups that the user was a member of will be left intact.</p> <h4 id='url-arguments-2'>URL arguments</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>user_id</code>*</td> <td><em>String</em> - Unique identifier for the user. Should match the ID the user has in your database.</td> </tr> </tbody></table> <p>* Required</p> <h4 id='response-body-3'>Response body</h4> <p>Returns an object with a <code>deleted</code> key on success (or if the user already didn't exist - this call is idempotent).</p> <h2 id='list-users'>List users</h2> <blockquote> <p><code>GET /users</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/users <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"list"</span><span class="p">,</span><span class="w"> </span><span class="s2">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"user"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"email"</span><span class="p">:</span><span class="w"> </span><span class="s2">"maxie@example.com"</span><span class="p">,</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Maxie Kris"</span><span class="p">,</span><span class="w"> </span><span class="s2">"signed_up_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-09-29T12:34:56.000+00:00"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"groups"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"memberships"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"10"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"user"</span><span class="p">,</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">],</span><span class="w"> </span><span class="s2">"has_more"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="s2">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/users"</span><span class="p">,</span><span class="w"> </span><span class="s2">"next_page_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/users?starting_after=10"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <blockquote> <p>Filter by email:</p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/users?email<span class="o">=</span>alice@example.com <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <p>Returns a list of your users.</p> <h4 id='query-parameters'>Query parameters</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>condition</code></td> <td><em>String</em> - Only include users that match the given condition. Can be used to filter any attribute. See <a href="#condition-filtering">Condition filtering</a>.</td> </tr> <tr> <td><code>email</code></td> <td><em>String</em> - Only include users whose <code>email</code> attribute equals this value.</td> </tr> <tr> <td><code>group_id</code></td> <td><em>String</em> - Only include users who are members of this group.</td> </tr> <tr> <td><code>limit</code></td> <td><em>Number</em> - See <a href="#pagination-query-parameters">Pagination</a>.</td> </tr> <tr> <td><code>order_by</code></td> <td><em>String or array of strings</em> - See <a href="#ordering">Ordering</a>. Fields that users can be ordered by: <code>created_at</code> (note that this is when the user was created with Userflow), <code>attributes.signed_up_at</code>, <code>attributes.last_seen_at</code>, <code>attributes.name</code>. Defaults to <code>created_at</code>.</td> </tr> <tr> <td><code>segment_id</code></td> <td><em>String</em> - Only include users in this segment. Find a segment's ID in the Userflow UI via the three-dot menu at the top right of the segment page.</td> </tr> <tr> <td><code>starting_after</code></td> <td><em>String</em> - See <a href="#pagination-query-parameters">Pagination</a>.</td> </tr> </tbody></table> <h4 id='response-body-4'>Response body</h4> <p>Returns a <a href="#the-list-object">list object</a> with a <code>data</code> property that contains an array of <a href="#the-user-object">user objects</a>.</p> <h1 id='groups-companies'>Groups/companies</h1> <p>Groups are used to group multiple users together. In your business, groups may correspond to e.g. companies, teams or departments.</p> <p>Like users, groups can have attributes. Events can also be associated with groups.</p> <p>With groups, you can orchestrate the flows a user sees:</p> <ul> <li>...based on behavior of other users in a group. Example: Show a flow if no one in a group has created a "widget" yet.</li> <li>...based on multiple groups that the user is a member of. Example: Show a flow if the group the user is currently working on matches some condition.</li> </ul> <p>Note that the Groups feature is only available in certain plans. Check your <a href="https://userflow.com/app/_/settings/billing">Billing page</a> or <a href="mailto:support@userflow.com">reach out to us to ask</a>.</p> <h2 id='the-group-object'>The group object</h2> <blockquote> <p>Example group object:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ab82c312-b3a4-4feb-870c-53dd336f955e"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"group"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Acme Inc."</span><span class="p">,</span><span class="w"> </span><span class="s2">"billing_plan"</span><span class="p">:</span><span class="w"> </span><span class="s2">"plus"</span><span class="p">,</span><span class="w"> </span><span class="s2">"signed_up_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-09-29T12:34:56.000+00:00"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>id</code></td> <td><em>String</em> - Unique identifier for the group/company. Should match the ID the group/company has in your database.</td> </tr> <tr> <td><code>object</code></td> <td><em>String</em> - Represents the object's type. Always <code>group</code>.</td> </tr> <tr> <td><code>attributes</code></td> <td><em>Object</em> - A map with all the group's attributes. You can add any attributes you want here.</td> </tr> <tr> <td><code>created_at</code></td> <td><em>String</em> - ISO 8601 date time representing when the group was created with Userflow. Note that this is not the time the group was signed up in your app - use an attribute such as <code>signed_up_at</code> in the <code>attributes</code> object for that.</td> </tr> <tr> <td><code>memberships</code></td> <td><em>Array of <a href="#the-group-membership-object">group membership objects</a></em> - A list of all the group's memberships. Memberships can hold attributes that describe each user's role for just this group (e.g. their access level). Each membership object will point to an actual <a href="#the-user-object">user object</a>. Defaults to <code>null</code>, but can be <a href="#expanding-objects">expanded</a> using <code>?expand=memberships</code>, or <code>?expand=memberships.user</code> if you want to expand both the group's memberships and each user.</td> </tr> <tr> <td><code>users</code></td> <td><em>Array of <a href="#the-user-object">user objects</a></em> - A list of all users that are members of this group. This field is only useful if you're not interested in membership attributes, in which case you should use <code>memberships</code>. Defaults to <code>null</code>, but can be <a href="#expanding-objects">expanded</a> using <code>?expand=users</code>.</td> </tr> </tbody></table> <h2 id='create-or-update-a-group'>Create or update a group</h2> <blockquote> <p><code>POST /groups</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/groups <span class="se">\</span> -XPOST <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> <span class="se">\</span> -H <span class="s1">'Content-Type: application/json'</span> <span class="se">\</span> -d <span class="s1">'{ "id": "ab82c312-b3a4-4feb-870c-53dd336f955e", "attributes": { "name": "Acme Inc.", "billing_plan": "plus", "signed_up_at": "2022-09-29T12:34:56.000+00:00" } }'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ab82c312-b3a4-4feb-870c-53dd336f955e"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"group"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Acme Inc."</span><span class="p">,</span><span class="w"> </span><span class="s2">"billing_plan"</span><span class="p">:</span><span class="w"> </span><span class="s2">"plus"</span><span class="p">,</span><span class="w"> </span><span class="s2">"signed_up_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-09-29T12:34:56.000+00:00"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"memberships"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"users"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Creating and updating a group is the same operation. If a group with the same ID doesn't already exist in Userflow, it will be created. If it already exists, the given attributes will be merged into the existing group's attributes.</p> <p>Note that groups can also be created/updated by embedding <code>groups</code> or <code>memberships</code> when <a href="#create-or-update-a-user-with-memberships">creating or updating a user</a>.</p> <h4 id='request-body-2'>Request body</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>id</code>*</td> <td><em>String</em> - Unique identifier for the group. Should match the ID the group has in your database.</td> </tr> <tr> <td><code>attributes</code></td> <td><em>Object</em> - A map with attributes to update for the group. You can add any attributes you want here. Existing attributes not included in the request will not be touched. Attribute values can either be supplied as literal values (string, boolean, number) or as operations (set, set_once, add, subtract). See <a href="#attributes">Attributes</a>.</td> </tr> </tbody></table> <p>* Required</p> <h4 id='response-body-5'>Response body</h4> <p>Returns the created/updated <a href="#the-group-object">group object</a>.</p> <h2 id='get-a-group'>Get a group</h2> <blockquote> <p><code>GET /groups/:group_id</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/groups/ab82c312-b3a4-4feb-870c-53dd336f955e <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ab82c312-b3a4-4feb-870c-53dd336f955e"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"group"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Acme Inc."</span><span class="p">,</span><span class="w"> </span><span class="s2">"billing_plan"</span><span class="p">:</span><span class="w"> </span><span class="s2">"plus"</span><span class="p">,</span><span class="w"> </span><span class="s2">"signed_up_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-09-29T12:34:56.000+00:00"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"memberships"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"users"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Retrieves a group including all its attributes.</p> <h4 id='url-arguments-3'>URL arguments</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>group_id</code>*</td> <td><em>String</em> - Unique identifier for the group. Should match the ID the group has in your database.</td> </tr> </tbody></table> <p>* Required</p> <h4 id='response-body-6'>Response body</h4> <p>Returns the <a href="#the-group-object">group object</a>, if found. Responds with <code>404 Not Found</code> if not.</p> <h2 id='delete-a-group'>Delete a group</h2> <blockquote> <p><code>DELETE /groups/:group_id</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/groups/ab82c312-b3a4-4feb-870c-53dd336f955e <span class="se">\</span> -XDELETE <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ab82c312-b3a4-4feb-870c-53dd336f955e"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"group"</span><span class="p">,</span><span class="w"> </span><span class="s2">"deleted"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Permanently deletes a group including all their attributes, memberships and events. It cannot be undone. Users who were members of the group will be left intact.</p> <h4 id='url-arguments-4'>URL arguments</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>group_id</code>*</td> <td><em>String</em> - Unique identifier for the group. Should match the ID the group has in your database.</td> </tr> </tbody></table> <p>* Required</p> <h4 id='response-body-7'>Response body</h4> <p>Returns an object with a <code>deleted</code> key on success (or if the group already didn't exist - this call is idempotent).</p> <h2 id='list-groups'>List groups</h2> <blockquote> <p><code>GET /groups</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/groups <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"list"</span><span class="p">,</span><span class="w"> </span><span class="s2">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"group"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Acme Inc."</span><span class="p">,</span><span class="w"> </span><span class="s2">"signed_up_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-09-29T12:34:56.000+00:00"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"memberships"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"users"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"10"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"group"</span><span class="p">,</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">],</span><span class="w"> </span><span class="s2">"has_more"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="s2">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/groups"</span><span class="p">,</span><span class="w"> </span><span class="s2">"next_page_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/groups?starting_after=10"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Returns a list of groups.</p> <h4 id='query-parameters-2'>Query parameters</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>condition</code></td> <td><em>String</em> - Only include groups that match the given condition. Can be used to filter any attribute. See <a href="#condition-filtering">Condition filtering</a>.</td> </tr> <tr> <td><code>email</code></td> <td><em>String</em> - Only include users whose <code>email</code> attribute equals this value.</td> </tr> <tr> <td><code>limit</code></td> <td><em>Number</em> - See <a href="#pagination-query-parameters">Pagination</a>.</td> </tr> <tr> <td><code>order_by</code></td> <td><em>String or array of strings</em> - See <a href="#ordering">Ordering</a>. Fields that groups can be ordered by: <code>created_at</code> (note that this is when the group was created with Userflow), <code>attributes.name</code>. Defaults to <code>created_at</code>.</td> </tr> <tr> <td><code>segment_id</code></td> <td><em>String</em> - Only include groups in this segment. Find a segment's ID in the Userflow UI via the three-dot menu at the top right of the segment page.</td> </tr> <tr> <td><code>starting_after</code></td> <td><em>String</em> - See <a href="#pagination-query-parameters">Pagination</a>.</td> </tr> <tr> <td><code>user_id</code></td> <td><em>String</em> - Only include groups that this user is a member of.</td> </tr> </tbody></table> <h4 id='response-body-8'>Response body</h4> <p>Returns a <a href="#the-list-object">list object</a> with a <code>data</code> property that contains an array of <a href="#the-group-object">group objects</a>.</p> <h1 id='group-memberships'>Group memberships</h1> <p>Group memberships represent the many-to-many association between users and groups. One user can be a member of multiple groups. One group can have multiple users as members.</p> <p>Memberships can hold attributes related to the user's role in a specific group. One user may be the Owner of one group and an Admin of another group. One group can have both an Owner and an Admin. You can't put the user's role in either the user's attributes or the group's attributes. Instead, you put it in the membership's attributes.</p> <h2 id='the-group-membership-object'>The group membership object</h2> <blockquote> <p>Example group membership object:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"e9b32bd0-63cb-415e-9c4f-477c85b92f97"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"group_membership"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"role"</span><span class="p">:</span><span class="w"> </span><span class="s2">"admin"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"group"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"group_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ab82c312-b3a4-4feb-870c-53dd336f955e"</span><span class="p">,</span><span class="w"> </span><span class="s2">"user"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"user_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2a845972-4cde-4cb4-ba14-5cb2fc15ec4c"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>id</code></td> <td><em>String</em> - Unique identifier for the membership set by Userflow.</td> </tr> <tr> <td><code>object</code></td> <td><em>String</em> - Represents the object's type. Always <code>group_membership</code>.</td> </tr> <tr> <td><code>attributes</code></td> <td><em>Object</em> - A map with all the membership's attributes. You can add any attributes you want here.</td> </tr> <tr> <td><code>created_at</code></td> <td><em>String</em> - ISO 8601 date time representing when the membership was created with Userflow. Note that this is not the time the member user signed up in your app - use an attribute such as <code>signed_up_at</code> in the user's <code>attributes</code> object for that.</td> </tr> <tr> <td><code>group</code></td> <td><em><a href="#the-group-object">Group object</a></em> - Defaults to <code>null</code>, but can be <a href="#expanding-objects">expanded</a> using <code>?expand=group</code>.</td> </tr> <tr> <td><code>group_id</code></td> <td><em>String</em> - The ID of group.</td> </tr> <tr> <td><code>user</code></td> <td><em><a href="#the-user-object">User object</a></em> - Defaults to <code>null</code>, but can be <a href="#expanding-objects">expanded</a> using <code>?expand=user</code>.</td> </tr> <tr> <td><code>user_id</code></td> <td><em>String</em> - The ID of user.</td> </tr> </tbody></table> <h2 id='create-or-update-a-group-membership'>Create or update a group membership</h2> <p>Memberships can't be created/updated directly. Instead, <a href="#create-or-update-a-user-with-memberships">create or update a user</a> and embed a list of group membership objects in the <code>memberships</code> field.</p> <h2 id='remove-a-user-from-a-group'>Remove a user from a group</h2> <blockquote> <p><code>DELETE /group_memberships?user_id=:user_id&group_id=:group_id</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/group_memberships?user_id<span class="o">=</span>123&group_id<span class="o">=</span>456 <span class="se">\</span> -XDELETE <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"e9b32bd0-63cb-415e-9c4f-477c85b92f97"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"group_membership"</span><span class="p">,</span><span class="w"> </span><span class="s2">"deleted"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Removes a single user from a single group. Leaves the user and the group themselves intact.</p> <h4 id='url-arguments-5'>URL arguments</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>group_id</code>*</td> <td><em>String</em> - Unique identifier for the group. Should match the ID the group has in your database.</td> </tr> <tr> <td><code>user_id</code>*</td> <td><em>String</em> - Unique identifier for the user. Should match the ID the user has in your database.</td> </tr> </tbody></table> <p>* Required</p> <h4 id='response-body-9'>Response body</h4> <p>Returns an object with a <code>deleted</code> key on success (or if the user already wasn't a member of the group - this call is idempotent).</p> <h2 id='list-group-memberships'>List group memberships</h2> <p>Memberships can't be listed directly. Instead, retrieve <a href="#retrive-a-user">a user</a> or <a href="#retrive-a-group">a group</a> and use the <code>?expand</code> query parameter to <a href="#expanding-objects">expand</a> the user/group's <code>memberships</code>.</p> <h1 id='events'>Events</h1> <p>You can track events for users and groups for analytics purposes or to segment and personalize your flows.</p> <p>Events can be either associated with just a user, just a group, or both a user and a group.</p> <h2 id='the-event-object'>The event object</h2> <blockquote> <p>Example event object:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"4738382"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"event"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"plan_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"plus"</span><span class="p">,</span><span class="w"> </span><span class="s2">"plan_price"</span><span class="p">:</span><span class="w"> </span><span class="mi">199</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-11-29T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"group"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"group_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ab82c312-b3a4-4feb-870c-53dd336f955e"</span><span class="p">,</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"subscription_activated"</span><span class="p">,</span><span class="w"> </span><span class="s2">"time"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-11-29T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"user"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"user_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"c2dfad13-ee7d-4fb2-9b4f-d450716b4791"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>id</code></td> <td><em>String</em> - Unique identifier for the event.</td> </tr> <tr> <td><code>object</code></td> <td><em>String</em> - Represents the object's type. Always <code>event</code>.</td> </tr> <tr> <td><code>attributes</code></td> <td><em>Object</em> - A map of attributes associated with the event. You can add any attributes you want here.</td> </tr> <tr> <td><code>created_at</code></td> <td><em>String</em> - ISO 8601 date time representing when the event was created with Userflow.</td> </tr> <tr> <td><code>group</code></td> <td><em><a href="#the-group-object">Group object</a></em> - Defaults to <code>null</code>, but can be <a href="#expanding-objects">expanded</a> using <code>?expand=group</code>.</td> </tr> <tr> <td><code>group_id</code></td> <td><em>String</em> - ID of the group the event is associated with (if any). Should match the ID the group has in your database.</td> </tr> <tr> <td><code>name</code></td> <td><em>String</em> - Event name (the action the user performed).</td> </tr> <tr> <td><code>time</code></td> <td><em>String</em> - ISO 8601 date time representing when the event actually happened. This may differ from <code>created_at</code> if your integration explicitly sends <code>time</code>, or if you have imported historic events.</td> </tr> <tr> <td><code>user</code></td> <td><em><a href="#the-user-object">User object</a></em> - Defaults to <code>null</code>, but can be <a href="#expanding-objects">expanded</a> using <code>?expand=user</code>.</td> </tr> <tr> <td><code>user_id</code></td> <td><em>String</em> - ID of the user the event is associated with (if any). Should match the ID the user has in your database.</td> </tr> </tbody></table> <h2 id='track-an-event'>Track an event</h2> <blockquote> <p><code>POST /events</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/events <span class="se">\</span> -XPOST <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> <span class="se">\</span> -H <span class="s1">'Content-Type: application/json'</span> <span class="se">\</span> -d <span class="s1">'{ "user_id": "c2dfad13-ee7d-4fb2-9b4f-d450716b4791", "name": "subscription_activated", "attributes": { "plan_name": "plus", "plan_price": 199 } }'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"4738382"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"event"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"plan_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"plus"</span><span class="p">,</span><span class="w"> </span><span class="s2">"plan_price"</span><span class="p">:</span><span class="w"> </span><span class="mi">199</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-11-29T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"group_id"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"group"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"subscription_activated"</span><span class="p">,</span><span class="w"> </span><span class="s2">"time"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-11-29T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"user_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"c2dfad13-ee7d-4fb2-9b4f-d450716b4791"</span><span class="p">,</span><span class="w"> </span><span class="s2">"user"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Stores an event associated with a user and/or a group.</p> <h4 id='request-body-3'>Request body</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>attributes</code></td> <td><em>Object</em> - A map of attributes associated with the event. You can add any attributes you want here. Attribute names (the keys) must conform to our <a href="#attribute-naming">Attribute naming rules</a>.</td> </tr> <tr> <td><code>group_id</code>*</td> <td><em>String</em> - ID of the group the event is associated with (if any). Should match the ID the group has in your database.</td> </tr> <tr> <td><code>name</code>**</td> <td><em>String</em> - Name of the action a user has performed. Must conform to our <a href="#event-naming">Event naming rules</a>.</td> </tr> <tr> <td><code>time</code></td> <td><em>String</em> - ISO 8601 date time representing when the event actually happened. If not set, it'll default to the curren time when the event is received.</td> </tr> <tr> <td><code>user_id</code>*</td> <td><em>String</em> - ID of the user the event is associated with (if any). Should match the ID the user has in your database.</td> </tr> </tbody></table> <p>* One (or both) of <code>user_id</code> and <code>group_id</code> is required.<br> ** Required</p> <h4 id='response-body-10'>Response body</h4> <p>Returns the created <a href="#the-event-object">event object</a>.</p> <h1 id='content'>Content</h1> <p>Content is a common term for flows, checklists and launchers.</p> <p>Note that content is versioned. The actual <em>contents</em> of content objects are found in <a href="#content-versions">content versions</a>.</p> <h2 id='the-content-object'>The content object</h2> <blockquote> <p>Example content object:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"54bce034-1303-4200-a09a-780a2eee355d"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"content"</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"draft_version_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"152a63cc-0a49-475a-a8e4-5f89bee94fe6"</span><span class="p">,</span><span class="w"> </span><span class="s2">"draft_version"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Example flow"</span><span class="p">,</span><span class="w"> </span><span class="s2">"published_version_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"c8eeb97b-43aa-47d9-bed2-a3d964900977"</span><span class="p">,</span><span class="w"> </span><span class="s2">"published_version"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"flow"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>id</code></td> <td><em>String</em> - Unique identifier for the content object.</td> </tr> <tr> <td><code>object</code></td> <td><em>String</em> - Represents the object's type. Always <code>content</code>.</td> </tr> <tr> <td><code>created_at</code></td> <td><em>String</em> - ISO 8601 date time representing when the content object was first created.</td> </tr> <tr> <td><code>draft_version_id</code></td> <td><em>String</em> - The ID of the version currently in the Builder.</td> </tr> <tr> <td><code>draft_version</code></td> <td><em><a href="#the-content-version-object">Content version object</a></em> - Defaults to <code>null</code>, but can be <a href="#expanding-objects">expanded</a> using <code>?expand=draft_version</code>.</td> </tr> <tr> <td><code>name</code></td> <td><em>String</em> - Name given in the Builder.</td> </tr> <tr> <td><code>published_version_id</code></td> <td><em>String</em> - The ID of the version currently published in the environment.</td> </tr> <tr> <td><code>published_version</code></td> <td><em><a href="#the-content-version-object">Content version object</a></em> - Defaults to <code>null</code>, but can be <a href="#expanding-objects">expanded</a> using <code>?expand=published_version</code>.</td> </tr> <tr> <td><code>type</code></td> <td><em>String</em> - Indicates what type of content it is. One of: <code>checklist</code>, <code>flow</code>, <code>launcher</code></td> </tr> </tbody></table> <h2 id='get-a-content-object'>Get a content object</h2> <blockquote> <p><code>GET /content/:content_id</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/content/54bce034-1303-4200-a09a-780a2eee355d <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"54bce034-1303-4200-a09a-780a2eee355d"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"content"</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"draft_version_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"152a63cc-0a49-475a-a8e4-5f89bee94fe6"</span><span class="p">,</span><span class="w"> </span><span class="s2">"draft_version"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Example flow"</span><span class="p">,</span><span class="w"> </span><span class="s2">"published_version_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"c8eeb97b-43aa-47d9-bed2-a3d964900977"</span><span class="p">,</span><span class="w"> </span><span class="s2">"published_version"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"flow"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Retrieves a single content object by its ID.</p> <h4 id='url-arguments-6'>URL arguments</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>content_id</code>*</td> <td><em>String</em> - Unique identifier for the content object.</td> </tr> </tbody></table> <p>* Required</p> <h4 id='response-body-11'>Response body</h4> <p>Returns the <a href="#the-content-object">content object</a>, if found. Responds with <code>404 Not Found</code> if not.</p> <h2 id='list-content'>List content</h2> <blockquote> <p><code>GET /content</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/content <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"list"</span><span class="p">,</span><span class="w"> </span><span class="s2">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"54bce034-1303-4200-a09a-780a2eee355d"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"content"</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"draft_version_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"152a63cc-0a49-475a-a8e4-5f89bee94fe6"</span><span class="p">,</span><span class="w"> </span><span class="s2">"draft_version"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Example flow"</span><span class="p">,</span><span class="w"> </span><span class="s2">"published_version_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"c8eeb97b-43aa-47d9-bed2-a3d964900977"</span><span class="p">,</span><span class="w"> </span><span class="s2">"published_version"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"flow"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"f7ddbadb-4368-4367-b728-b69610450cbd"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"content"</span><span class="p">,</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">],</span><span class="w"> </span><span class="s2">"has_more"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="s2">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/content"</span><span class="p">,</span><span class="w"> </span><span class="s2">"next_page_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/content?starting_after=f7ddbadb-4368-4367-b728-b69610450cbd"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <blockquote> <p>Filter by type:</p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/content?type<span class="o">=</span>checklist <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <p>Returns a list of your content.</p> <h4 id='query-parameters-3'>Query parameters</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>limit</code></td> <td><em>Number</em> - See <a href="#pagination-query-parameters">Pagination</a>.</td> </tr> <tr> <td><code>order_by</code></td> <td><em>String or array of strings</em> - See <a href="#ordering">Ordering</a>. Fields that content objects can be ordered by: <code>created_at</code>, <code>name</code>. Defaults to <code>created_at</code>.</td> </tr> <tr> <td><code>starting_after</code></td> <td><em>String</em> - See <a href="#pagination-query-parameters">Pagination</a>.</td> </tr> <tr> <td><code>type</code></td> <td><em>String</em> - Only include content objects of the given type. Supported values: <code>checklist</code>, <code>flow</code>, <code>launcher</code>.</td> </tr> </tbody></table> <h4 id='response-body-12'>Response body</h4> <p>Returns a <a href="#the-list-object">list object</a> with a <code>data</code> property that contains an array of <a href="#the-content-object">content objects</a>.</p> <h1 id='content-versions'>Content versions</h1> <p>Content (flows, checklists and launchers) is versioned. A new version is automatically created by Userflow when new edits are made and when publishing content.</p> <h2 id='the-content-version-object'>The content version object</h2> <blockquote> <p>Example content version object:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"152a63cc-0a49-475a-a8e4-5f89bee94fe6"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"content_version"</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Optional example description"</span><span class="p">,</span><span class="w"> </span><span class="s2">"edited_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-06-29T23:45:67.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"number"</span><span class="p">:</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="s2">"questions"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"tasks"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>id</code></td> <td><em>String</em> - Unique identifier for the content object.</td> </tr> <tr> <td><code>object</code></td> <td><em>String</em> - Represents the object's type. Always <code>content_version</code>.</td> </tr> <tr> <td><code>created_at</code></td> <td><em>String</em> - ISO 8601 date time representing when the content object was first created.</td> </tr> <tr> <td><code>description</code></td> <td><em>String</em> - Optional user-provided description of the version.</td> </tr> <tr> <td><code>edited_at</code></td> <td><em>String</em> - ISO 8601 date time representing when the version was last edited (or published, in which case it was frozen at this moment).</td> </tr> <tr> <td><code>number</code></td> <td><em>Number</em> - The version number. Version numbers are incremental for each content object.</td> </tr> <tr> <td><code>questions</code></td> <td><em>Array of <a href="#the-question-object">question objects</a></em> - A list of all questions in the version. Only flows can have questions. Defaults to <code>null</code>, but can be <a href="#expanding-objects">expanded</a> using <code>?expand=questions</code>.</td> </tr> <tr> <td><code>tasks</code></td> <td><em>Array of <a href="#the-checklist-task-object">checklist task objects</a></em> - A list of all tasks in the version. Only checklists can have tasks. Defaults to <code>null</code>, but can be <a href="#expanding-objects">expanded</a> using <code>?expand=tasks</code>.</td> </tr> </tbody></table> <h2 id='the-question-object'>The question object</h2> <blockquote> <p>Example question object:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"d3af62f1-4de3-4c9a-b20c-85b85dce0fef"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"question"</span><span class="p">,</span><span class="w"> </span><span class="s2">"cvid"</span><span class="p">:</span><span class="w"> </span><span class="s2">"540649a1-9443-4b59-90a2-2262e58744f8"</span><span class="p">,</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Example Question"</span><span class="p">,</span><span class="w"> </span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"text"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>id</code></td> <td><em>String</em> - Unique identifier for the question. <strong>Important:</strong> The ID of questions change between versions. When a new version is created, all its components are copied from the old version, but with new <code>id</code> values. You can use <code>cvid</code> for an ID that's stable across versions.</td> </tr> <tr> <td><code>object</code></td> <td><em>String</em> - Represents the object's type. Always <code>question</code>.</td> </tr> <tr> <td><code>cvid</code></td> <td><em>String</em> - Short for Cross-Version ID. An ID that stays the same for the logically same question across versions. Use this if you ever have to refer to a question - not <code>id</code>, since it'll change between versions.</td> </tr> <tr> <td><code>name</code></td> <td><em>String</em> - Name given to the question in the Builder.</td> </tr> <tr> <td><code>type</code></td> <td><em>String</em> - Type of question. Supported values: <code>multiline_text</code>, <code>multiple_choice</code>, <code>nps</code>, <code>stars</code>, <code>text</code>.</td> </tr> </tbody></table> <h2 id='the-checklist-task-object'>The checklist task object</h2> <blockquote> <p>Example checklist task object:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1a8152f8-41cf-4e10-9e74-71cafd6dc8b2"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"checklist_task"</span><span class="p">,</span><span class="w"> </span><span class="s2">"cvid"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ad157908-b182-4585-b0ea-21fdcb2da684"</span><span class="p">,</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Example Task"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>id</code></td> <td><em>String</em> - Unique identifier for the task. <strong>Important:</strong> The ID of tasks change between versions. When a new version is created, all its components are copied from the old version, but with new <code>id</code> values. You can use <code>cvid</code> for an ID that's stable across versions.</td> </tr> <tr> <td><code>object</code></td> <td><em>String</em> - Represents the object's type. Always <code>checklist_task</code>.</td> </tr> <tr> <td><code>cvid</code></td> <td><em>String</em> - Short for Cross-Version ID. An ID that stays the same for the logically same task across versions. Use this if you ever have to refer to a task - not <code>id</code>, since it'll change between versions.</td> </tr> <tr> <td><code>name</code></td> <td><em>String</em> - Name given to the task in the Builder.</td> </tr> </tbody></table> <h2 id='get-a-content-version'>Get a content version</h2> <blockquote> <p><code>GET /content_versions/:version_id</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/content_versions/152a63cc-0a49-475a-a8e4-5f89bee94fe6 <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"152a63cc-0a49-475a-a8e4-5f89bee94fe6"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"content_version"</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Optional example description"</span><span class="p">,</span><span class="w"> </span><span class="s2">"edited_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-06-29T23:45:67.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"number"</span><span class="p">:</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="s2">"questions"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"tasks"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Retrieves a single content version by its ID.</p> <h4 id='url-arguments-7'>URL arguments</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>version_id</code>*</td> <td><em>String</em> - Unique identifier for the content version.</td> </tr> </tbody></table> <p>* Required</p> <h4 id='response-body-13'>Response body</h4> <p>Returns the <a href="#the-content-version-object">content version object</a>, if found. Responds with <code>404 Not Found</code> if not.</p> <h2 id='list-content-versions'>List content versions</h2> <blockquote> <p><code>GET /content_versions</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/content_versions?content_id<span class="o">=</span>54bce034-1303-4200-a09a-780a2eee355d <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"list"</span><span class="p">,</span><span class="w"> </span><span class="s2">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"152a63cc-0a49-475a-a8e4-5f89bee94fe6"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"content_version"</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Optional example description"</span><span class="p">,</span><span class="w"> </span><span class="s2">"edited_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-06-29T23:45:67.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"number"</span><span class="p">:</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="s2">"questions"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"tasks"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"c8eeb97b-43aa-47d9-bed2-a3d964900977"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"content_version"</span><span class="p">,</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">],</span><span class="w"> </span><span class="s2">"has_more"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="s2">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/content_versions"</span><span class="p">,</span><span class="w"> </span><span class="s2">"next_page_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/content_versions?starting_after=c8eeb97b-43aa-47d9-bed2-a3d964900977"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <blockquote> <p>Filter by version number:</p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/content_versions?content_id<span class="o">=</span>54bce034-1303-4200-a09a-780a2eee355d&number<span class="o">=</span>3 <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <p>Returns a list of versions for a specific content object.</p> <h4 id='query-parameters-4'>Query parameters</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>content_id</code>*</td> <td><em>String</em> - List versions of this content object. Must be supplied - we currently don't support listing versions across content objects.</td> </tr> <tr> <td><code>limit</code></td> <td><em>Number</em> - See <a href="#pagination-query-parameters">Pagination</a>.</td> </tr> <tr> <td><code>number</code></td> <td><em>Number</em> - Filter by version number to find a specific version.</td> </tr> <tr> <td><code>order_by</code></td> <td><em>String or array of strings</em> - See <a href="#ordering">Ordering</a>. Fields that content objects can be ordered by: <code>number</code>. Defaults to <code>number</code>.</td> </tr> <tr> <td><code>starting_after</code></td> <td><em>String</em> - See <a href="#pagination-query-parameters">Pagination</a>.</td> </tr> </tbody></table> <p>* Required</p> <h4 id='response-body-14'>Response body</h4> <p>Returns a <a href="#the-list-object">list object</a> with a <code>data</code> property that contains an array of <a href="#the-content-version-object">content version objects</a>.</p> <h1 id='content-sessions'>Content sessions</h1> <p>A session is a specific user's journey through a specific content object (flow, checklist or launcher). It tracks their progress and records survey answers they provide.</p> <h2 id='the-content-session-object'>The content session object</h2> <blockquote> <p>Example content session object:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"33af21fd-f025-43fc-a492-cf5179b38ee3"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"content_session"</span><span class="p">,</span><span class="w"> </span><span class="s2">"answers"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"completed_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:35:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"completed"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="s2">"content_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"54bce034-1303-4200-a09a-780a2eee355d"</span><span class="p">,</span><span class="w"> </span><span class="s2">"content"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"group_id"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"group"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"is_preview"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> </span><span class="s2">"last_activity_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:35:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"launcher_activated"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> </span><span class="s2">"progress"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1"</span><span class="p">,</span><span class="w"> </span><span class="s2">"user_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"34907ae0-24e0-4261-ac31-3c7299a354c0"</span><span class="p">,</span><span class="w"> </span><span class="s2">"user"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"version_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"152a63cc-0a49-475a-a8e4-5f89bee94fe6"</span><span class="p">,</span><span class="w"> </span><span class="s2">"version"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>id</code></td> <td><em>String</em> - Unique identifier for the content session.</td> </tr> <tr> <td><code>object</code></td> <td><em>String</em> - Represents the object's type. Always <code>content_session</code>.</td> </tr> <tr> <td><code>answers</code></td> <td><em>Array of <a href="#the-content-session-answer-object">content session answer objects</a></em> - A list of all answers provided by the user to survey questions in the flow. Only flow sessions can have answers. Defaults to <code>null</code>, but can be <a href="#expanding-objects">expanded</a> using <code>?expand=answers</code>.</td> </tr> <tr> <td><code>completed_at</code></td> <td><em>String</em> - ISO 8601 date time representing when the flow/checklist was completed. <code>null</code> if not completed.</td> </tr> <tr> <td><code>completed</code></td> <td><em>Boolean</em> - Whether the flow/checklist has been completed. For flows, this means when the user visited a goal step. For checklists, this means that the user completed all tasks.</td> </tr> <tr> <td><code>content_id</code></td> <td><em>String</em> - The ID of the content object (i.e. flow/checklist/launcher) that this session is running.</td> </tr> <tr> <td><code>content</code></td> <td><em><a href="#the-content-object">Content object</a></em> - Defaults to <code>null</code>, but can be <a href="#expanding-objects">expanded</a> using <code>?expand=content</code>.</td> </tr> <tr> <td><code>created_at</code></td> <td><em>String</em> - ISO 8601 date time representing when the session was first created.</td> </tr> <tr> <td><code>group_id</code></td> <td><em>String</em> - The ID of a group, if this session was started under a group.</td> </tr> <tr> <td><code>group</code></td> <td><em><a href="#the-group-object">Group object</a></em> - Defaults to <code>null</code>, but can be <a href="#expanding-objects">expanded</a> using <code>?expand=group</code>.</td> </tr> <tr> <td><code>is_preview</code></td> <td><em>Boolean</em> - <code>true</code> if the session was started by a team member previewing a draft version.</td> </tr> <tr> <td><code>last_activity_at</code></td> <td><em>String</em> - ISO 8601 date time representing when the user last interacted with the content (e.g. went to the next step, expanded a checklist etc.).</td> </tr> <tr> <td><code>launcher_activated</code></td> <td><em>Boolean</em> - If this is a session launcher, will be <code>true</code> if the user has activated the launcher by e.g. hovering over or clicking the target element.</td> </tr> <tr> <td><code>progress</code></td> <td><em>Decimal string</em> - A decimal representation of the user's progress through the flow. <code>1</code> means that the flow is fully completed (100%). <code>0.4</code> means that the user is 40% through.</td> </tr> <tr> <td><code>user_id</code></td> <td><em>String</em> - The ID of the user seeing the content.</td> </tr> <tr> <td><code>user</code></td> <td><em><a href="#the-user-object">User object</a></em> - Defaults to <code>null</code>, but can be <a href="#expanding-objects">expanded</a> using <code>?expand=user</code>.</td> </tr> <tr> <td><code>version_id</code></td> <td><em>String</em> - The ID of the version that this session is running.</td> </tr> <tr> <td><code>version</code></td> <td><em><a href="#the-version-object">Content object</a></em> - Defaults to <code>null</code>, but can be <a href="#expanding-objects">expanded</a> using <code>?expand=version</code>.</td> </tr> </tbody></table> <h2 id='the-content-session-answer-object'>The content session answer object</h2> <blockquote> <p>Example content session answer object:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"23dec03f-3de6-4e89-89e6-eed0785eecd0"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"content_session_answer"</span><span class="p">,</span><span class="w"> </span><span class="s2">"answer_type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"text"</span><span class="p">,</span><span class="w"> </span><span class="s2">"answer_value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"I really like your app!"</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"question_cvid"</span><span class="p">:</span><span class="w"> </span><span class="s2">"540649a1-9443-4b59-90a2-2262e58744f8"</span><span class="p">,</span><span class="w"> </span><span class="s2">"question_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Feedback"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>id</code></td> <td><em>String</em> - Unique identifier for the answer.</td> </tr> <tr> <td><code>object</code></td> <td><em>String</em> - Represents the object's type. Always <code>content_session_answer</code>.</td> </tr> <tr> <td><code>answer_type</code></td> <td><em>String</em> - Represents the data type of the answer. Supported values: <code>number</code>, <code>text</code>, <code>list</code>.</td> </tr> <tr> <td><code>answer_value</code></td> <td><em>String</em> - The answer given by the user. If <code>answer_type</code> is <code>text</code>, then <code>answer_value</code> is a string. If <code>answer_type</code> is <code>number</code>, then <code>answer_value</code> is a numeric string. If <code>answer_type</code> is <code>list</code>, <code>answer_value</code> is an array of strings.</td> </tr> <tr> <td><code>created_at</code></td> <td><em>String</em> - ISO 8601 date time representing when the answer was provided.</td> </tr> <tr> <td><code>question_cvid</code></td> <td><em>String</em> - The Cross-Version ID of the question that was answered (<code>cvid</code> of a <a href="#the-question-object">question object</a>).</td> </tr> <tr> <td><code>question_name</code></td> <td><em>String</em> - The name of the question that was answered (<code>name</code> of a <a href="#the-question-object">question object</a>).</td> </tr> </tbody></table> <h2 id='get-a-content-session'>Get a content session</h2> <blockquote> <p><code>GET /content_sessions/:session_id</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/content_sessions/33af21fd-f025-43fc-a492-cf5179b38ee3 <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"33af21fd-f025-43fc-a492-cf5179b38ee3"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"content_session"</span><span class="p">,</span><span class="w"> </span><span class="s2">"answers"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"completed_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:35:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"completed"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="s2">"content_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"54bce034-1303-4200-a09a-780a2eee355d"</span><span class="p">,</span><span class="w"> </span><span class="s2">"content"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"group_id"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"group"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"is_preview"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> </span><span class="s2">"last_activity_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:35:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"launcher_activated"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> </span><span class="s2">"progress"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1"</span><span class="p">,</span><span class="w"> </span><span class="s2">"user_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"34907ae0-24e0-4261-ac31-3c7299a354c0"</span><span class="p">,</span><span class="w"> </span><span class="s2">"user"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"version_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"152a63cc-0a49-475a-a8e4-5f89bee94fe6"</span><span class="p">,</span><span class="w"> </span><span class="s2">"version"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Retrieves a single content session by its ID.</p> <h4 id='url-arguments-8'>URL arguments</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>session_id</code>*</td> <td><em>String</em> - Unique identifier for the content session.</td> </tr> </tbody></table> <p>* Required</p> <h4 id='response-body-15'>Response body</h4> <p>Returns the <a href="#the-content-session-object">content session object</a>, if found. Responds with <code>404 Not Found</code> if not.</p> <h2 id='list-content-sessions'>List content sessions</h2> <blockquote> <p><code>GET /content_sessions</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/content_sessions?content_id<span class="o">=</span>54bce034-1303-4200-a09a-780a2eee355d <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"list"</span><span class="p">,</span><span class="w"> </span><span class="s2">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"33af21fd-f025-43fc-a492-cf5179b38ee3"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"content_session"</span><span class="p">,</span><span class="w"> </span><span class="s2">"answers"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"completed_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:35:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"completed"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="s2">"content_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"54bce034-1303-4200-a09a-780a2eee355d"</span><span class="p">,</span><span class="w"> </span><span class="s2">"content"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"group_id"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"group"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"is_preview"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> </span><span class="s2">"last_activity_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:35:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"launcher_activated"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> </span><span class="s2">"progress"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1"</span><span class="p">,</span><span class="w"> </span><span class="s2">"user_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"34907ae0-24e0-4261-ac31-3c7299a354c0"</span><span class="p">,</span><span class="w"> </span><span class="s2">"user"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"version_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"152a63cc-0a49-475a-a8e4-5f89bee94fe6"</span><span class="p">,</span><span class="w"> </span><span class="s2">"version"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"0a2b7674-ed69-4261-9389-ce68e32077d2"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"content_session"</span><span class="p">,</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">],</span><span class="w"> </span><span class="s2">"has_more"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="s2">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/content_sessions"</span><span class="p">,</span><span class="w"> </span><span class="s2">"next_page_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/content_sessions?starting_after=0a2b7674-ed69-4261-9389-ce68e32077d2"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <blockquote> <p>Check if a specific user has seen a specific flow:</p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/content_sessions?user_id<span class="o">=</span>34907ae0-24e0-4261-ac31-3c7299a354c0&content_id<span class="o">=</span>54bce034-1303-4200-a09a-780a2eee355d&number<span class="o">=</span>3 <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <p>Returns a list of content sessions.</p> <h4 id='query-parameters-5'>Query parameters</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>content_id</code></td> <td><em>String</em> - Only include sessions for this content object.</td> </tr> <tr> <td><code>limit</code></td> <td><em>Number</em> - See <a href="#pagination-query-parameters">Pagination</a>.</td> </tr> <tr> <td><code>order_by</code></td> <td><em>String or array of strings</em> - See <a href="#ordering">Ordering</a>. Fields that content objects can be ordered by: <code>created_at</code>, <code>last_activity_at</code>. Defaults to <code>created_at</code>.</td> </tr> <tr> <td><code>starting_after</code></td> <td><em>String</em> - See <a href="#pagination-query-parameters">Pagination</a>.</td> </tr> <tr> <td><code>user_id</code></td> <td><em>String</em> - Only include sessions for this user.</td> </tr> </tbody></table> <h4 id='response-body-16'>Response body</h4> <p>Returns a <a href="#the-list-object">list object</a> with a <code>data</code> property that contains an array of <a href="#the-content-session-object">content session objects</a>.</p> <h1 id='attribute-definitions'>Attribute definitions</h1> <p>You can associate any attributes with users/events that you want. Userflow keeps track of all the attributes you use through attribute definitions.</p> <p>Attribute definitions are automatically created when you send new attributes not seen by Userflow before. It's currently not possible to create/update/delete attribute definitions through this API.</p> <h2 id='the-attribute-definition-object'>The attribute definition object</h2> <blockquote> <p>Example attribute definition object:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"dfb0c3ed-a8d1-4e73-8b95-b307fa322c3a"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute_definition"</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"data_type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"datetime"</span><span class="p">,</span><span class="w"> </span><span class="s2">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"When user first signed up in your app"</span><span class="p">,</span><span class="w"> </span><span class="s2">"display_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Signed Up"</span><span class="p">,</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"signed_up_at"</span><span class="p">,</span><span class="w"> </span><span class="s2">"scope"</span><span class="p">:</span><span class="w"> </span><span class="s2">"user"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>id</code></td> <td><em>String</em> - Unique identifier for the attribute definition.</td> </tr> <tr> <td><code>object</code></td> <td><em>String</em> - Represents the object's type. Always <code>attribute_definition</code>.</td> </tr> <tr> <td><code>created_at</code></td> <td><em>String</em> - ISO 8601 date time representing when attribute definition was first created.</td> </tr> <tr> <td><code>data_type</code></td> <td><em>String</em> - Indicates what type of values can be used for the attributes. See <a href="#attribute-data-types">Attribute data types</a> for possible values for custom attributes. Userflow-internal attributes can use the following data types (these attributes are not writable through the API): <code>checklist_task</code>, <code>content</code>, <code>content_session</code>, <code>content_version</code>, <code>flow_step</code>, <code>random_ab</code>, <code>random_number</code>.</td> </tr> <tr> <td><code>description</code></td> <td><em>String</em> - A human-readable description of what the attribute is used for. Can be changed in the Userflow Dashboard.</td> </tr> <tr> <td><code>display_name</code></td> <td><em>String</em> - A human-readable name for the attribute. Used in most Userflow UI when referring to attributes. Can be changed in the Userflow Dashboard.</td> </tr> <tr> <td><code>name</code></td> <td><em>String</em> - The key used when setting the attribute value through the <code>attributes</code> object in e.g. <a href="#create-or-update-a-user">Create or update a user</a>. Cannot be changed once an attribute definition is created.</td> </tr> <tr> <td><code>scope</code></td> <td><em>String</em> - Defines which objects this attribute can be associated with. Supported values: <code>event</code>, <code>group</code>, <code>group_membership</code>, <code>user</code>.</td> </tr> </tbody></table> <h2 id='list-attribute-definitions'>List attribute definitions</h2> <blockquote> <p><code>GET /attribute_definitions</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/attribute_definitions <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"list"</span><span class="p">,</span><span class="w"> </span><span class="s2">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"dfb0c3ed-a8d1-4e73-8b95-b307fa322c3a"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute_definition"</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"data_type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"datetime"</span><span class="p">,</span><span class="w"> </span><span class="s2">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"When user first signed up in your app"</span><span class="p">,</span><span class="w"> </span><span class="s2">"display_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Signed Up"</span><span class="p">,</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"signed_up_at"</span><span class="p">,</span><span class="w"> </span><span class="s2">"scope"</span><span class="p">:</span><span class="w"> </span><span class="s2">"user"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"f6293417-f262-4ff6-88b7-3afce56a0de1"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attribute_definition"</span><span class="p">,</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">],</span><span class="w"> </span><span class="s2">"has_more"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="s2">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/attribute_definitions"</span><span class="p">,</span><span class="w"> </span><span class="s2">"next_page_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/attribute_definitions?starting_after=f6293417-f262-4ff6-88b7-3afce56a0de1"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <blockquote> <p>Filter by scope:</p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/attribute_definitions?scope<span class="o">=</span>user <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <blockquote> <p>Filter by event names:</p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/attribute_definitions?event_name[]<span class="o">=</span>flow_started&event_name[]<span class="o">=</span>flow_ended <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <p>Returns a list of your attribute definitions.</p> <h4 id='query-parameters-6'>Query parameters</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>event_name</code></td> <td><em>String or array of strings</em> - Only include attribute definitions used in the given event(s).</td> </tr> <tr> <td><code>limit</code></td> <td><em>Number</em> - See <a href="#pagination-query-parameters">Pagination</a>.</td> </tr> <tr> <td><code>order_by</code></td> <td><em>String or array of strings</em> - See <a href="#ordering">Ordering</a>. Fields that attribute definitions can be ordered by: <code>created_at</code>, <code>display_name</code>, <code>name</code>. Defaults to <code>display_name</code>.</td> </tr> <tr> <td><code>scope</code></td> <td><em>String</em> - Only include attribute definitions with the given scope. Supported values: <code>event</code>, <code>group</code>, <code>group_membership</code>, <code>user</code>.</td> </tr> <tr> <td><code>starting_after</code></td> <td><em>String</em> - See <a href="#pagination-query-parameters">Pagination</a>.</td> </tr> </tbody></table> <h4 id='response-body-17'>Response body</h4> <p>Returns a <a href="#the-list-object">list object</a> with a <code>data</code> property that contains an array of <a href="#the-attribute-definition-object">attribute definition objects</a>.</p> <h1 id='event-definitions'>Event definitions</h1> <p>You can track any custom event with Userflow that you want. Userflow keeps track of all the events you use through event definitions.</p> <p>Event definitions are automatically created when you track new events not seen by Userflow before. It's currently not possible to create/update/delete attribute definitions through this API.</p> <p>For tracking events, see <a href="#events">Events</a>.</p> <h2 id='the-event-definition-object'>The event definition object</h2> <blockquote> <p>Example event definition object:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"9cf1de05-9a3a-4719-b8a9-75316a5f86ce"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"event_definition"</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"A Userflow flow was started"</span><span class="p">,</span><span class="w"> </span><span class="s2">"display_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Flow Started"</span><span class="p">,</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"flow_started"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>id</code></td> <td><em>String</em> - Unique identifier for the event definition.</td> </tr> <tr> <td><code>object</code></td> <td><em>String</em> - Represents the object's type. Always <code>event_definition</code>.</td> </tr> <tr> <td><code>created_at</code></td> <td><em>String</em> - ISO 8601 date time representing when event definition was first created.</td> </tr> <tr> <td><code>description</code></td> <td><em>String</em> - A human-readable description of what the event means. Can be changed in the Userflow Dashboard.</td> </tr> <tr> <td><code>display_name</code></td> <td><em>String</em> - A human-readable name for the event. Used in most Userflow UI when referring to events. Can be changed in the Userflow Dashboard.</td> </tr> <tr> <td><code>name</code></td> <td><em>String</em> - Used as the <code>name</code> field in <a href="#the-event-object">event objects</a>. Cannot be changed once an event definition is created.</td> </tr> </tbody></table> <h2 id='event-naming'>Event naming</h2> <p>Event names must consist only of a-z, A-Z, 0-9, underscores, dashes and spaces. We recommend using <code>snake_case</code> everywhere though. Events' human-friendly display names (e.g. "Subscription Activated" for <code>subscription_activated</code>) can also be configured in the Userflow UI.</p> <p>We recommend using event names consisting of a noun and a past-tense verb. Check out this great <a href="https://segment.com/academy/collecting-data/naming-conventions-for-clean-data/">event naming guide by Segment</a>.</p> <h2 id='list-event-definitions'>List event definitions</h2> <blockquote> <p><code>GET /event_definitions</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/event_definitions <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"list"</span><span class="p">,</span><span class="w"> </span><span class="s2">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"9cf1de05-9a3a-4719-b8a9-75316a5f86ce"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"event_definition"</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"A Userflow flow was started"</span><span class="p">,</span><span class="w"> </span><span class="s2">"display_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Flow Started"</span><span class="p">,</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"flow_started"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1821de25-316f-4b9a-b0e6-52e45f62a012"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"event_definition"</span><span class="p">,</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">],</span><span class="w"> </span><span class="s2">"has_more"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="s2">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/event_definitions"</span><span class="p">,</span><span class="w"> </span><span class="s2">"next_page_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/event_definitions?starting_after=1821de25-316f-4b9a-b0e6-52e45f62a012"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Returns a list of your event definitions.</p> <h4 id='query-parameters-7'>Query parameters</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>limit</code></td> <td><em>Number</em> - See <a href="#pagination-query-parameters">Pagination</a>.</td> </tr> <tr> <td><code>order_by</code></td> <td><em>String or array of strings</em> - See <a href="#ordering">Ordering</a>. Fields that event definitions can be ordered by: <code>created_at</code>, <code>display_name</code>, <code>name</code>. Defaults to <code>display_name</code>.</td> </tr> <tr> <td><code>starting_after</code></td> <td><em>String</em> - See <a href="#pagination-query-parameters">Pagination</a>.</td> </tr> </tbody></table> <h4 id='response-body-18'>Response body</h4> <p>Returns a <a href="#the-list-object">list object</a> with a <code>data</code> property that contains an array of <a href="#the-attribute-definition-object">event definition objects</a>.</p> <h1 id='webhook-subscriptions'>Webhook subscriptions</h1> <p>You can create webhook subscriptions to be notified when certain events happen in your Userflow account.</p> <p>When e.g. a user is created or a user event is tracked, Userflow will send a <code>POST</code> request to a URL of your choosing. Often this URL would hit your own servers, so your back-end can react to the webhook.</p> <h2 id='the-webhook-subscription-object'>The webhook subscription object</h2> <blockquote> <p>Example webhook subscription object:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"c8783643-7f16-4a02-b736-4f5a327f8231"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"webhook_subscription"</span><span class="p">,</span><span class="w"> </span><span class="s2">"api_version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2020-01-03"</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"disabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> </span><span class="s2">"topics"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"user"</span><span class="p">,</span><span class="w"> </span><span class="s2">"event"</span><span class="p">],</span><span class="w"> </span><span class="s2">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://example.com/hooks/userflow"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>You create webhook subscription objects to subscribe to notifications.</p> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>id</code></td> <td><em>String</em> - Unique identifier for the webhook subscription.</td> </tr> <tr> <td><code>object</code></td> <td><em>String</em> - Represents the object's type. Always <code>webhook_subscription</code>.</td> </tr> <tr> <td><code>api_version</code></td> <td><em>String</em> - The API version notifications will be sent to <code>url</code> with. See <a href="#versioning">Versioning</a>.</td> </tr> <tr> <td><code>created_at</code></td> <td><em>String</em> - ISO 8601 date time representing when the webhook subscription was created.</td> </tr> <tr> <td><code>disabled</code></td> <td><em>boolean</em> - Used to temporarily make Userflow stop sending notifications (when set to <code>true</code>).</td> </tr> <tr> <td><code>secret</code></td> <td><em>String</em> - The subscription's secret, used to generate <a href="#webhook-signatures">webhook signatures</a>. Only returned at creation (<code>POST /webhook_subscriptions</code>).</td> </tr> <tr> <td><code>topics</code></td> <td><em>Array of strings</em> - The <a href="#webhook-topics">webhook topics</a> your subscription will be notified of.</td> </tr> <tr> <td><code>url</code></td> <td><em>String</em> - The URL Userflow should send <code>POST</code> requests to when there are new notifications.</td> </tr> </tbody></table> <h2 id='the-webhook-notification-object'>The webhook notification object</h2> <blockquote> <p>Example webhook notification object for when an event is tracked:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ec3a21f3-88fe-43e8-8711-cfc803aaad54"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"webhook_notification"</span><span class="p">,</span><span class="w"> </span><span class="s2">"api_version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2020-01-03"</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-11-29T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"4738382"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"event"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"plan_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"plus"</span><span class="p">,</span><span class="w"> </span><span class="s2">"plan_price"</span><span class="p">:</span><span class="w"> </span><span class="mi">199</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-11-29T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"subscription_activated"</span><span class="p">,</span><span class="w"> </span><span class="s2">"time"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-11-29T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"user_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"c2dfad13-ee7d-4fb2-9b4f-d450716b4791"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"topic"</span><span class="p">:</span><span class="w"> </span><span class="s2">"event.tracked.subscription_activated"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <blockquote> <p>Example webhook notification object for when a user is updated:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"c30d70fd-eb53-4132-bc99-90792677497b"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"webhook_notification"</span><span class="p">,</span><span class="w"> </span><span class="s2">"api_version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2020-01-03"</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-11-29T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"4738382"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"user"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"email"</span><span class="p">:</span><span class="w"> </span><span class="s2">"annabelle@example.com"</span><span class="p">,</span><span class="w"> </span><span class="s2">"email_verified"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Annabelle Terry"</span><span class="p">,</span><span class="w"> </span><span class="s2">"project_count"</span><span class="p">:</span><span class="w"> </span><span class="mi">17</span><span class="p">,</span><span class="w"> </span><span class="s2">"signed_up_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-09-29T12:34:56.000+00:00"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"groups"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s2">"memberships"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"previous_attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"email_verified"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> </span><span class="s2">"project_count"</span><span class="p">:</span><span class="w"> </span><span class="mi">14</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"updated_attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"email_verified"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="s2">"project_count"</span><span class="p">:</span><span class="w"> </span><span class="mi">17</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"topic"</span><span class="p">:</span><span class="w"> </span><span class="s2">"user.updated"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Userflow creates webhook notifications when certain things happen in your account (e.g. a user is created), and sends them to your webhook subscriptions.</p> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>id</code></td> <td><em>String</em> - Unique identifier for the webhook notification.</td> </tr> <tr> <td><code>object</code></td> <td><em>String</em> - Represents the object's type. Always <code>webhook_notification</code>.</td> </tr> <tr> <td><code>api_version</code></td> <td><em>String</em> - The API version of the webhook subscription this notification was sent for. See <a href="#versioning">Versioning</a>.</td> </tr> <tr> <td><code>created_at</code></td> <td><em>String</em> - ISO 8601 date time representing when the webhook notification was created.</td> </tr> <tr> <td><code>data</code></td> <td><em>Object</em> - Holds details about the notification.</td> </tr> <tr> <td><code>data.object</code></td> <td><em>Object</em> - The object of the notification. E.g. for the <code>user.created</code> topic, <code>data.object</code> will be a <a href="#the-user-object">user object</a>, and for the <code>event.tracked.<name></code> topic it'll be an <a href="#the-event-object">event object</a>.</td> </tr> <tr> <td><code>data.previous_attributes</code></td> <td><em>Object</em> - Only set in <code><object>.updated</code> topic notifications. Contains the old values of all changed attributes as they were before the change that caused this notification.</td> </tr> <tr> <td><code>data.updated_attributes</code></td> <td><em>Object</em> - Only set in <code><object>.updated</code> topic notifications. Contains the new values of all changed attributes.</td> </tr> <tr> <td><code>topic</code></td> <td><em>String</em> - The notification's <a href="#webhook-topics">webhook topic</a>.</td> </tr> </tbody></table> <h2 id='webhook-topics'>Webhook topics</h2> <p>Webhook subscriptions only receive notifications for topics they subscribe to.</p> <p>Topics are namespaced. If you subscribe to e.g. <code>user</code>, you get'll all user-related notifications such as <code>user.created</code> and <code>user.updated</code>.</p> <p>You can also use <code>*</code> to subscribe to all topics.</p> <table><thead> <tr> <th>Topic</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>*</code></td> <td>Matches <strong>ALL</strong> topics.</td> </tr> <tr> <td><code>event</code></td> <td>Matches all event-related topics.</td> </tr> <tr> <td><code>event.tracked</code></td> <td>When any event is tracked.</td> </tr> <tr> <td><code>event.tracked.<name></code></td> <td>When a <code><name></code> event is tracked. You can use any of <code>name</code> value from your <a href="#event-definitions">event definitions</a>. Example: <code>event.tracked.flow_started</code></td> </tr> <tr> <td><code>group</code></td> <td>Matches all group-related topics.</td> </tr> <tr> <td><code>group.created</code></td> <td>When a new group is created with Userflow.</td> </tr> <tr> <td><code>group.updated</code></td> <td>When an existing group is updated.</td> </tr> <tr> <td><code>user</code></td> <td>Matches all user-related topics.</td> </tr> <tr> <td><code>user.created</code></td> <td>When a new user is created with Userflow.</td> </tr> <tr> <td><code>user.updated</code></td> <td>When an existing user is updated.</td> </tr> </tbody></table> <h2 id='receiving-webhooks'>Receiving webhooks</h2> <blockquote> <p>Example webhook notification request headers (what Userflow sends to your server):</p> </blockquote> <pre class="highlight plaintext"><code>POST /hooks/userflow Host: your.app.com Content-Type: application/json; charset=utf-8 User-Agent: Userflow/1.0 (https://userflow.com/docs/webhooks) Userflow-Signature: t=1578424823,v1=5cb0c1733224ad819f93dcf4b902cd714c83afd4e9e95412f4bc6cd1b94a3aac </code></pre> <blockquote> <p>Example webhook notification request body (what Userflow sends to your server):</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ec3a21f3-88fe-43e8-8711-cfc803aaad54"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"webhook_notification"</span><span class="p">,</span><span class="w"> </span><span class="s2">"api_version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2020-01-03"</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-11-29T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"4738382"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"event"</span><span class="p">,</span><span class="w"> </span><span class="s2">"attributes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"plan_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"plus"</span><span class="p">,</span><span class="w"> </span><span class="s2">"plan_price"</span><span class="p">:</span><span class="w"> </span><span class="mi">199</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-11-29T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"subscription_activated"</span><span class="p">,</span><span class="w"> </span><span class="s2">"time"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-11-29T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"user_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"c2dfad13-ee7d-4fb2-9b4f-d450716b4791"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s2">"topic"</span><span class="p">:</span><span class="w"> </span><span class="s2">"event.tracked.subscription_activated"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Userflow will send a <code>POST</code> request to your webhook subscription's <code>url</code> every time there's a new notification that matches your subscription's <code>topics</code>.</p> <p>The request body is a <a href="#the-webhook-notification-object">webhook notification object</a>.</p> <p><strong>We strongly recommend that you <a href="#webhook-signatures">verify the signature header</a> to avoid fake requests from third parties.</strong></p> <p>If you handle the webhook successfully, you must return a <code>2xx</code> (e.g. <code>200</code>) status code to tell Userflow that everything is in order. If Userflow does not receive a 2xx response status code within a timeout of 15 seconds, Userflow will retry the request using exponential backoff. Userflow will give up after 3 days.</p> <p>If your server has to perform time-consuming operations, we recommend that you enqueue it to run in the background, and acknowledge the webhook with a <code>200 OK</code> response immediately. This is to avoid the webhook request from timing out and then being re-delivered unnecessarily again later.</p> <p>Even though webhooks are sent almost immediately by Userflow, we do not guarantee the order of events. A new user may be created, then shortly after be updated. Your app should expect possibly receiving the <code>user.updated</code> notification for that user before the <code>user.created</code> notification.</p> <h2 id='webhook-signatures'>Webhook signatures</h2> <blockquote> <p>Example <code>Userflow-Signature</code> header:</p> </blockquote> <pre class="highlight plaintext"><code>Userflow-Signature: t=1578424823,v1=5cb0c1733224ad819f93dcf4b902cd714c83afd4e9e95412f4bc6cd1b94a3aac </code></pre> <p>Userflow includes a <code>Userflow-Signature</code> header to let you verify that webhook notifications are in fact coming from Userflow and not a third party.</p> <p>The <code>Userflow-Signature</code> header also includes a timestamp, which mitigates <a href="https://en.wikipedia.org/wiki/Replay_attack">replay attacks</a>, where an attacker intercepts a valid payload and signature, and then re-transmits it later. This timestamp is also part of the signed payload, which means an attacker can't change the timestamp without also invalidating the signature. If a timestamp is too old (e.g. > 5 minutes), we recommend that you ignore the request. We recommend using <a href="https://en.wikipedia.org/wiki/Network_Time_Protocol">Network Time Protocol (NTP)</a> to ensure that your server鈥檚 clock is accurate (Userflow uses NTP, too).</p> <p>You need the <code>secret</code> returned when <a href="#create-a-webhook-subscription">creating your webhook subscription</a> to verify signatures. Secrets belong to subscriptions, meaning if your account has multiple subscriptions then they'll each have their own unique secret.</p> <p>The <code>Userflow-Signature</code> header is on the form <code>t=<timestamp>,v1=<signature></code>. <code><timestamp></code> is a UNIX timestamp (in seconds) representing when the signature was generated. Userflow generates a new signature every time we attempt to deliver a notification (including on retries). <code><signature></code> is an HMAC signature. We use <code>v1</code> as key for the signature to able to support new signature schemes in the future. See example on the right.</p> <h3 id='verifying-signatures'>Verifying signatures</h3> <blockquote> <p>Example JavaScript implementation:</p> </blockquote> <pre class="highlight javascript"><code><span class="c1">// This function will throw if the signature is invalid</span> <span class="kd">function</span> <span class="nx">verifyUserflowSignature</span><span class="p">(</span><span class="nx">body</span><span class="p">,</span> <span class="nx">header</span><span class="p">,</span> <span class="nx">secret</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Make sure body is a string (not a buffer)</span> <span class="nx">body</span> <span class="o">=</span> <span class="nx">Buffer</span><span class="p">.</span><span class="nx">isBuffer</span><span class="p">(</span><span class="nx">body</span><span class="p">)</span> <span class="p">?</span> <span class="nx">body</span><span class="p">.</span><span class="nx">toString</span><span class="p">(</span><span class="s1">'utf8'</span><span class="p">)</span> <span class="p">:</span> <span class="nx">body</span> <span class="c1">// Reject if timestamp is more than 5 minutes ago</span> <span class="kd">let</span> <span class="nx">tolerance</span> <span class="o">=</span> <span class="mi">300</span> <span class="c1">// seconds</span> <span class="c1">// Extract header information</span> <span class="kd">let</span> <span class="nx">t</span> <span class="kd">let</span> <span class="nx">signature</span> <span class="nx">header</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">','</span><span class="p">).</span><span class="nx">forEach</span><span class="p">(</span><span class="nx">part</span> <span class="o">=></span> <span class="p">{</span> <span class="kd">let</span> <span class="p">[</span><span class="nx">k</span><span class="p">,</span> <span class="nx">v</span><span class="p">]</span> <span class="o">=</span> <span class="nx">part</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">'='</span><span class="p">)</span> <span class="k">if</span> <span class="p">(</span><span class="nx">k</span> <span class="o">===</span> <span class="s1">'t'</span><span class="p">)</span> <span class="p">{</span> <span class="nx">t</span> <span class="o">=</span> <span class="nx">v</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">k</span> <span class="o">===</span> <span class="s1">'v1'</span><span class="p">)</span> <span class="p">{</span> <span class="nx">signature</span> <span class="o">=</span> <span class="nx">v</span> <span class="p">}</span> <span class="p">})</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">t</span><span class="p">)</span> <span class="p">{</span> <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">'Userflow-Signature header check failed: Missing t'</span><span class="p">)</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">signature</span><span class="p">)</span> <span class="p">{</span> <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span> <span class="s1">'Userflow-Signature header check failed: Missing v1 signature'</span> <span class="p">)</span> <span class="p">}</span> <span class="c1">// Verify timestamp age</span> <span class="kd">let</span> <span class="nx">timestampAge</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Date</span><span class="p">.</span><span class="nx">now</span><span class="p">()</span> <span class="o">/</span> <span class="mi">1000</span><span class="p">)</span> <span class="o">-</span> <span class="nx">t</span> <span class="k">if</span> <span class="p">(</span><span class="nx">timestampAge</span> <span class="o">></span> <span class="nx">tolerance</span><span class="p">)</span> <span class="p">{</span> <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span> <span class="s2">`Userflow-Signature header check failed: Timestamp is more than </span><span class="p">${</span><span class="nx">tolerance</span><span class="p">}</span><span class="s2"> seconds ago`</span> <span class="p">)</span> <span class="p">}</span> <span class="c1">// Compare signatures</span> <span class="kd">let</span> <span class="nx">signedPayload</span> <span class="o">=</span> <span class="nx">t</span> <span class="o">+</span> <span class="s1">'.'</span> <span class="o">+</span> <span class="nx">body</span> <span class="kd">let</span> <span class="nx">expectedSignature</span> <span class="o">=</span> <span class="nx">crypto</span> <span class="p">.</span><span class="nx">createHmac</span><span class="p">(</span><span class="s1">'sha256'</span><span class="p">,</span> <span class="nx">secret</span><span class="p">)</span> <span class="p">.</span><span class="nx">update</span><span class="p">(</span><span class="nx">signedPayload</span><span class="p">,</span> <span class="s1">'utf8'</span><span class="p">)</span> <span class="p">.</span><span class="nx">digest</span><span class="p">(</span><span class="s1">'hex'</span><span class="p">)</span> <span class="k">if</span> <span class="p">(</span><span class="nx">signature</span> <span class="o">!==</span> <span class="nx">expectedSignature</span><span class="p">)</span> <span class="p">{</span> <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span> <span class="s1">'Userflow-Signature header check failed: Incorrect signature'</span> <span class="p">)</span> <span class="p">}</span> <span class="c1">// Signature is OK!</span> <span class="p">}</span> </code></pre> <blockquote> <p>Example of using <code>verifyUserflowSignature</code> in Express.js handler:</p> </blockquote> <pre class="highlight javascript"><code><span class="kr">const</span> <span class="nx">secret</span> <span class="o">=</span> <span class="s1">'whsec_...'</span> <span class="c1">// Make sure the handler gets the body as a raw string</span> <span class="kr">const</span> <span class="nx">parser</span> <span class="o">=</span> <span class="nx">bodyParser</span><span class="p">.</span><span class="nx">raw</span><span class="p">({</span><span class="na">type</span><span class="p">:</span> <span class="s1">'application/json'</span><span class="p">})</span> <span class="nx">app</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="s1">'/hooks/userflow'</span><span class="p">,</span> <span class="nx">parser</span><span class="p">,</span> <span class="p">(</span><span class="nx">request</span><span class="p">,</span> <span class="nx">response</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span> <span class="c1">// Verify signature</span> <span class="k">try</span> <span class="p">{</span> <span class="nx">verifyUserflowSignature</span><span class="p">(</span> <span class="nx">request</span><span class="p">.</span><span class="nx">body</span><span class="p">,</span> <span class="nx">request</span><span class="p">.</span><span class="nx">headers</span><span class="p">[</span><span class="s1">'userflow-signature'</span><span class="p">],</span> <span class="nx">secret</span> <span class="p">)</span> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nx">response</span><span class="p">.</span><span class="nx">status</span><span class="p">(</span><span class="mi">400</span><span class="p">).</span><span class="nx">json</span><span class="p">({</span><span class="na">error</span><span class="p">:</span> <span class="nx">e</span><span class="p">.</span><span class="nx">message</span><span class="p">})</span> <span class="p">}</span> <span class="c1">// TODO: Do your thing with the notification</span> <span class="kd">let</span> <span class="nx">notification</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">request</span><span class="p">.</span><span class="nx">body</span><span class="p">)</span> <span class="c1">// Reply 200 OK to tell Userflow everything is good</span> <span class="k">return</span> <span class="nx">response</span><span class="p">.</span><span class="nx">json</span><span class="p">({</span><span class="na">ok</span><span class="p">:</span> <span class="kc">true</span><span class="p">})</span> <span class="p">})</span> </code></pre> <p>Here's how to verify that the <code>Userflow-Signature</code> header is valid:</p> <ol> <li>Obtain the header value, the raw request body (as a raw string, not a parsed JSON object), and your webhook subscription <code>secret</code>.</li> <li>Extract the timestamp and signature from the header: Split the header by <code>,</code>, then split each pair by <code>=</code>, then get the timestamp from the pair with key <code>t</code> and the signature from the pair with key <code>v1</code>.</li> <li>If the timestamp is more than e.g. 300 seconds (5 minutes) in the past, then reject the request.</li> <li>Build the signed payload by concatenating the timestamp, a period (<code>.</code>), and the raw request body (as a string).</li> <li>Calculate the expected signature by computing an HMAC with the SHA256 hash function, using the webhook subscription <code>secret</code> as the key, and the signed payload (from step 4) as the message.</li> <li>Compare the actual signature (from step 2) with the expected signature (from step 5). Reject the request if they don't match.</li> </ol> <h2 id='create-a-webhook-subscription'>Create a webhook subscription</h2> <blockquote> <p><code>POST /webhook_subscriptions</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/webhook_subscriptions <span class="se">\</span> -XPOST <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> <span class="se">\</span> -H <span class="s1">'Content-Type: application/json'</span> <span class="se">\</span> -d <span class="s1">'{ "api_version": "2020-01-03", "url": "https://example.com/hooks/userflow", "topics": ["user", "event"] }'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"c8783643-7f16-4a02-b736-4f5a327f8231"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"webhook_subscription"</span><span class="p">,</span><span class="w"> </span><span class="s2">"api_version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2020-01-03"</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"disabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> </span><span class="s2">"secret"</span><span class="p">:</span><span class="w"> </span><span class="s2">"whsec_56nfnf5isvf5pldjcyesd4rxeq"</span><span class="p">,</span><span class="w"> </span><span class="s2">"topics"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"user"</span><span class="p">,</span><span class="w"> </span><span class="s2">"event"</span><span class="p">],</span><span class="w"> </span><span class="s2">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://example.com/hooks/userflow"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Creates a new webhook subscription.</p> <p>Notifications will immediately begin sending to <code>url</code> for all events occurring going forward. See <a href="#receiving-webhooks">Receiving webhooks</a>.</p> <h4 id='request-body-4'>Request body</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>api_version</code></td> <td><em>String</em> - The API version notifications will be sent to <code>url</code> with. See <a href="#versioning">Versioning</a>.</td> </tr> <tr> <td><code>topics</code></td> <td><em>Array of strings</em>* - The <a href="#webhook-topics">webhook topics</a> your subscription will be notified of.</td> </tr> <tr> <td><code>url</code></td> <td><em>String</em>* - The URL Userflow should send <code>POST</code> requests to when there are new notifications.</td> </tr> </tbody></table> <p>* Required</p> <h4 id='response-body-19'>Response body</h4> <p>Returns the created <a href="#the-webhook-subscription-object">webhook subscription object</a>.</p> <h2 id='get-a-webhook-subscription'>Get a webhook subscription</h2> <blockquote> <p><code>GET /webhook_subscriptions/:webhook_subscription_id</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/webhook_subscriptions/72a63cf6-91bf-4260-8258-a45db633d611 <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"c8783643-7f16-4a02-b736-4f5a327f8231"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"webhook_subscription"</span><span class="p">,</span><span class="w"> </span><span class="s2">"api_version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2020-01-03"</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"disabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> </span><span class="s2">"topics"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"user"</span><span class="p">,</span><span class="w"> </span><span class="s2">"event"</span><span class="p">],</span><span class="w"> </span><span class="s2">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://example.com/hooks/userflow"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Retrieves a webhook subscription.</p> <h4 id='url-arguments-9'>URL arguments</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>webhook_subscription_id</code>*</td> <td><em>String</em> - ID of the webhook subscription to retrieve.</td> </tr> </tbody></table> <p>* Required</p> <h4 id='response-body-20'>Response body</h4> <p>Returns the <a href="#the-webhook-subscription-object">webhook subscription object</a>, if found. Responds with <code>404 Not Found</code> if not.</p> <h2 id='update-a-webhook-subscription'>Update a webhook subscription</h2> <blockquote> <p><code>PATCH /webhook_subscriptions/:webhook_subscription_id</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/webhook_subscriptions <span class="se">\</span> -XPATCH <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> <span class="se">\</span> -H <span class="s1">'Content-Type: application/json'</span> <span class="se">\</span> -d <span class="s1">'{ "disabled": true }'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"c8783643-7f16-4a02-b736-4f5a327f8231"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"webhook_subscription"</span><span class="p">,</span><span class="w"> </span><span class="s2">"api_version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2020-01-03"</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"disabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="s2">"secret"</span><span class="p">:</span><span class="w"> </span><span class="s2">"whsec_56nfnf5isvf5pldjcyesd4rxeq"</span><span class="p">,</span><span class="w"> </span><span class="s2">"topics"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"user"</span><span class="p">,</span><span class="w"> </span><span class="s2">"event"</span><span class="p">],</span><span class="w"> </span><span class="s2">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://example.com/hooks/userflow"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Updates an existing webhook subscription.</p> <h4 id='url-arguments-10'>URL arguments</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>webhook_subscription_id</code>*</td> <td><em>String</em> - ID of the webhook subscription to update.</td> </tr> </tbody></table> <p>* Required</p> <h4 id='request-body-5'>Request body</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>api_version</code></td> <td><em>String</em> - The API version notifications will be sent to <code>url</code> with. See <a href="#versioning">Versioning</a>.</td> </tr> <tr> <td><code>topics</code></td> <td><em>Array of strings</em> - The <a href="#webhook-topics">webhook topics</a> your subscription will be notified of.</td> </tr> <tr> <td><code>url</code></td> <td><em>String</em> - The URL Userflow should send <code>POST</code> requests to when there are new notifications.</td> </tr> <tr> <td><code>disabled</code></td> <td><em>boolean</em> - Used to temporarily make Userflow stop sending notifications. If you set this to <code>true</code>, notifications will immediately stop being sent.</td> </tr> </tbody></table> <h4 id='response-body-21'>Response body</h4> <p>Returns the updated <a href="#the-webhook-subscription-object">webhook subscription object</a>.</p> <h2 id='delete-a-webhook-subscription'>Delete a webhook subscription</h2> <blockquote> <p><code>DELETE /webhook_subscriptions/:webhook_subscription_id</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/webhook_subscriptions/c8783643-7f16-4a02-b736-4f5a327f8231 <span class="se">\</span> -XDELETE <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"c8783643-7f16-4a02-b736-4f5a327f8231"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"webhook_subscription"</span><span class="p">,</span><span class="w"> </span><span class="s2">"deleted"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Permanently deletes a webhook subscription. It cannot be undone.</p> <p>Webhook notifications will immediately stop being sent to <code>url</code>.</p> <h4 id='url-arguments-11'>URL arguments</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>webhook_subscription_id</code>*</td> <td><em>String</em> - ID of the webhook subscription to delete.</td> </tr> </tbody></table> <p>* Required</p> <h4 id='response-body-22'>Response body</h4> <p>Returns an object with a <code>deleted</code> key on success (or if the webhook subscription already didn't exist - this call is idempotent).</p> <h2 id='list-webhook-subscriptions'>List webhook subscriptions</h2> <blockquote> <p><code>GET /webhook_subscriptions</code></p> </blockquote> <pre class="highlight shell tab-shell"><code>curl https://api.userflow.com/webhook_subscriptions <span class="se">\</span> -H <span class="s1">'Authorization: Bearer <api-key>'</span> <span class="se">\</span> -H <span class="s1">'Userflow-Version: 2020-01-03'</span> </code></pre> <blockquote> <p>Response:</p> </blockquote> <pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"list"</span><span class="p">,</span><span class="w"> </span><span class="s2">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"c8783643-7f16-4a02-b736-4f5a327f8231"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"webhook_subscription"</span><span class="p">,</span><span class="w"> </span><span class="s2">"api_version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2020-01-03"</span><span class="p">,</span><span class="w"> </span><span class="s2">"created_at"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2022-10-17T12:34:56.000+00:00"</span><span class="p">,</span><span class="w"> </span><span class="s2">"disabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> </span><span class="s2">"topics"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"user"</span><span class="p">,</span><span class="w"> </span><span class="s2">"event"</span><span class="p">],</span><span class="w"> </span><span class="s2">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://example.com/hooks/userflow"</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"0a55b4be-b327-4a2b-a66f-16d1f7bf6519"</span><span class="p">,</span><span class="w"> </span><span class="s2">"object"</span><span class="p">:</span><span class="w"> </span><span class="s2">"webhook_subscription"</span><span class="p">,</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">],</span><span class="w"> </span><span class="s2">"has_more"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="s2">"url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/webhook_subscriptions"</span><span class="p">,</span><span class="w"> </span><span class="s2">"next_page_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/webhook_subscriptions?starting_after=0a55b4be-b327-4a2b-a66f-16d1f7bf6519"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> <p>Returns a list of your webhook subscriptions.</p> <h4 id='query-parameters-8'>Query parameters</h4> <table><thead> <tr> <th>Key</th> <th>Description</th> </tr> </thead><tbody> <tr> <td><code>limit</code></td> <td><em>Number</em> - See <a href="#pagination-query-parameters">Pagination</a>.</td> </tr> <tr> <td><code>order_by</code></td> <td><em>String or array of strings</em> - See <a href="#ordering">Ordering</a>. Fields that webhook subscriptions can be ordered by: <code>created_at</code>, <code>url</code>. Defaults to <code>created_at</code>.</td> </tr> <tr> <td><code>starting_after</code></td> <td><em>String</em> - See <a href="#pagination-query-parameters">Pagination</a>.</td> </tr> </tbody></table> <h4 id='response-body-23'>Response body</h4> <p>Returns a <a href="#the-list-object">list object</a> with a <code>data</code> property that contains an array of <a href="#the-webhook-subscription-object">webhook subscription objects</a>.</p> </div> <div class="dark-box"> </div> </div> </body> </html>