In general terms, the OAuth process involves a Partner App getting authorization from the User to access their account. When authorized, an Access Token must be requested from Conversio. This token can then be included in requests to Conversio to Authenticate & Authorize the App to access a User’s account.

To begin the OAuth flow, the User is redirected to Conversio’s authorize endpoint:

https://app.conversio.com/oauth/authorize

Including the following parameters in the URL query string:

Parameter

Details

client_id:

string

The Partner App’s ID. Should be provided by Conversio.

redirect_uri:

string

Where the User will be redirected. Must match the value saved for the Partner App.

scope:

string, optional

The scopes that the App wishes to access on behalf of the User. Space separated values.

state:

string

A random string, at least 10 characters long, that is unique. This will be passed on to redirect_uri when the User accepts or rejects the authorization, and should be validated to be the same.

The User will be required to log-in to Conversio as needed.

If all required parameters are present and valid, the User can then review what permissions (scopes) are requested by which App. Conversely, any missing or invalid parameters will instead show an error page with a description of each problem.

At this point the User can Authorize or Reject the Authorization Request. When rejecting, the User will be redirected to redirect_uri with the following parameters in the URL query string:

Parameter

Details

error:

string

As per spec, will have the value “access_denied”.

error_description:

string

Will be “The user refused to authorize your App.”.

state:

string

Will be the same state value sent on the first request.

This ends the OAuth flow prematurely.

Conversely, when the User authorizes the App, an authorization code is generated that is bound to that User, the requested scopes and redirect_uri. The User is then redirected to redirect_uri with the code in the query params, and the same state that was received in the request, starting step 2.

Step 2: Receive Authorization Code

At this point the User has authorized the Partner App to access their account on their behalf. They will be redirected to redirect_uri and the URL query will include the following parameters:

Parameter

Details

code:

string

A 60 character hex string. This code represents the user’s authorization and must be used to get an Access Token in step 3. It is single-use and short-lived, expiring in 3 minutes.

state:

string

Must be the same value sent in the first request.

The state param’s value should be validated. It is exactly the same value as was sent in the first step. This ensures that the User is coming from the original request, and that the code isn’t from an earlier request intercepted by an attacker.

As a first step, the Access Token received from Conversio must be included in an Object (Hash for Ruby) at the key at. In that object, the current Unix time must be defined at the key ts. This timestamp is validated by Conversio to be within 3 minutes of current time, in an effort to prevent header reuse by attackers.

This object is then signed with HMAC, generating 3 Base64 encoded strings, separated by a period. This is the PoP Token.

Bulk Sync [POST]

Synchronize many receipts at once without sending the receipts. This is used to create a Receipt history for the recommendation engine. It will not create the receipts in Conversio.

You can upload 250 receipts per request.

Arguments

The receipt structure is the same as for Send except that you should
enclose the receipts in an array (see example request) and you can include a
status field to indicate if the historic order was actually completed or not.
See below.

Argument

Details

status:

string, optional

Status of the receipt, valid values are “pending”, “completed”, “cancelled” and “refunded”

Response 200 (success)

All receipts are valid.

Response 202 (partial success)

Some receipts are valid and some are invalid. The response specifies which
receipts failed to validate.

Valid receipts are accepted and processed and should not be re-uploaded.

Update a product [PUT]

PUT https://app.conversio.com/api/v1/products/{product_id}

Arguments

The product structure is the same as for Create a product
except that you can only update a single product.
Notice that the product should always be a full representation, not a
partial. The API does not support partial updates.

{"data":[{"id":"57b5aa3b046abfb053d80b52","title":"Awesome!","comment":"Taste and texture were all on point! ++ would buy again.","rating":5,"productId":"123456789","customerEmail":"happyguy@email.com","archived":false,"visible":true,"isTest":false,"createdAt":"2016-11-30T10:20:00.000Z"},{"id":"57b5aa3b046abfb053d80b59","title":"Quality Stuff","comment":"Product was great, but shipping took two weeks.","rating":4,"productId":"65443335","customerEmail":"mehdude@email.com","archived":false,"visible":false,"isTest":false,"createdAt":"2016-11-20T00:00:00.000Z"}],"meta":{"page":2,"pages":3,"total":5,"limit":2,"prevPage":"https://app.conversio.com/api/v1/product-reviews?page=1&limit=2","nextPage":"https://app.conversio.com/api/v1/product-reviews?page=3&limit=2"}}

List all Product Reviews [GET]

https://app.conversio.com/api/v1/product-reviews

OAuth Scopes: read_product_reviews, write_product_reviews

Query Parameters

Argument

Details

limit:

number, optional

How many Reviews to return. Default is 10.

page:

number, optional

Which page of Reviews to return. Default is 1.

visible:

bool, optional

Whether to return only visible (those that may appear in widgets) reviews or invisible.

archived:

bool, optional

Whether to return reviews that have been archived by the user. Default is false. Pass an empty string to disable this filter.

test:

bool, optional

Whether to return reviews created from test followups. Default is false. Pass an empty string to disable this filter.

Response 200

Response Body

Then endpoint returns an object with a data key that is an Array with limit Product Reviews in the shop, sorted by created date (recent on top). It also returns a meta key with paging info.

Each Product Review object includes the following info:

Key

Details

id:

string

The Product Review’s ID. Currently unused.

title:

string, optional

The Review’s title.

comment:

string, optional

The Review’s long comment.

rating:

number, optional

The Review’s rating, 1 to 5.

productId:

string

The ID of the Product that was reviewed.

customerEmail:

string, optional

The email address of the reviewer. May not exist when anonymous.

createdAt:

string, optional

When the Product Review was created. Is an ISO 8601 encoded date.

archived:

bool

A User may Archive a Product Review as a soft delete. Archived reviews aren’t shown in Widgets.

visible:

bool

Only visible reviews can appear in Widgets.

isTest:

bool

Whether this Review was created from a test FollowUp Email.

Abandoned Carts

Services related to managing Abandoned Carts. For the Email Campaigns triggered by Abandoned Carts, go to the next section.

The given TEMPLATE_ID does not belong to an existing template, if provided

The given CAMPAIGN_ID does not belong to an existing email, if provided

The requested template belongs to another shop than authenticated

The requested template belongs to another campaign than indicated

Response Body

The response body includes a data key which contains an object representation of the requested abandoned cart template:

Key

Details

id:

string

The ID for this email.

campaignId:

string

The ID for this template"s Campaign.

subject:

string

The subject used in the emails triggered by this template. May have user variables (e.g.: {firstName}).

title:

string

The template"s title, not customer-facing.

rule:

string

Rule for triggering an email from this template. Currently only “delay” is supported, which is a delay from a cart being abandoned.

period:

number

How many days must pass after the cart is abandoned to trigger an email from this template. Accumulates with periodHours.

periodHours:

string

How many hours must pass after the cart is abandoned to trigger an email from this template. Accumulates with period.

contentModules:

array

An array of the Content Modules in a template. These represent the content (copy, images, discounts, etc.) in a template. More details below.

Content Modules

{"contentModules":[{"position":0,"type":"text","context":{"body":"You left all of this stuff behind!"}},{"position":1,"type":"abandonedCart","context":{"quantity":"Quantity","description":"Description","unitPrice":"Unit Price","total":"Total","totalOrder":"Total","buttonColor":"#1990FF","primaryColor":"#1990FF","secondaryColor":"#0076E4","mainBackgroundColor":"#f8f8f8","actionTitle":"Get All My Stuff!"}},{"position":2,"type":"discountCoupon","context":{"title":"You Stuff, At a Discount!","description":"{{firstName}}, there"snowayyou"re leaving all that stuff in the cart. Grab this discount and check-out now!","actionTitle":"Start Shopping","expiresOn":"Expires On","primaryColor":"#1990FF","amount":10,"expiryPeriod":1,"emailLimit":false,"couponType":2,"backgroundColor":"#f8f8f8","onePerUser":true,"usageLimit":1}}]}

Each module has a position and a type. The 0-based position indicates where in the email the module appears (starting from top) and the type defines the kind of content.

The module"s content is in the context key. This object and its keys depend on the module"s type. These map directly to the content & settings in the Template editor, so we recommend referencing that in case any values are unclear.

{"data":[{"id":"57b5aa3b046abfb053d80b59","title":"4th of July Sales","liveAt":"2017-07-03:00:00.000Z","audience":{"lists":["marketing","57b5aa3b046abfb053d80b52"],"customerSegmentKind":"id","customerSegmentId":"57b5aa3b046abfb053d80b57","customerSegmentInline":{"criteria":[]}},"customerLists":[],"customerSegments":[],"status":"scheduled"},{"id":"57b5aa3b046abfb053d80b52","title":"Black Friday Announcement","liveAt":"2016-11-20T00:00:00.000Z","customerLists":["57b5aa3b046abfb053d80b53"],"customerSegments":["57b5aa3b046abfb053d80b57"],"status":"sent","sentAt":"2016-11-20T00:10:15.000Z"}],"meta":{"page":2,"pages":3,"total":5,"limit":2,"prevPage":"https://app.conversio.com/api/v1/newsletters?page=1&limit=2","nextPage":"https://app.conversio.com/api/v1/newsletters?page=3&limit=2"}}

List all Newsletters [GET]

https://app.conversio.com/api/v1/newsletters

OAuth Scopes: read_newsletter_template, write_newsletter_template

Query Parameters

Argument

Details

limit:

number, optional

How many Newsletters to return. Default is 10.

page:

number, optional

Which page of Newsletters to return. Default is 1.

status:

string, optional

Filters the Newsletters by status. Can be sent, scheduled, live or draft.

Response 200

Response Body

Then endpoint returns an object with a data key that is an Array with limit newsletters in the shop. The Newsletters are sorted by sentAt descending, liveAt ascending and createdAt descending. It also returns a meta key with paging info.

Each newsletter object includes the following info:

Key

Details

id:

string

The Newsletter’s ID. Use it when calling single-newsletter endpoints.

title:

string

The Newsletter’s title.

audience

object

The Newsletter’s audience. Can be comprised of one or more lists, a segment ID or an inline segment. See below.

liveAt:

string, optional

When the Newsletter is set to go live, if scheduled, or when it was set live, if sent or live. Is an ISO 8601 encoded date. Is omitted if the Newsletter is a draft.

status

string

The Newsletter’s current status. Must be one of “draft”, “scheduled”, “live”, or “sent”.

sentAt

string, optional

When the Newsletter was fully sent, if such is the case. Is an ISO 8601 encoded date.

customerLists (deprecated):

string[]

An array of IDs of Customer Lists who will receive / have received this Newsletter. May be empty. Deprecated in favour of audience.

customerSegments (deprecated):

string[]

An array of IDs of Customer Segments who will receive / have received this Newsletter. May be empty. Deprecated in favour of audience.

Audience

The Newsletter’s Audience. A Newsletter can be sent to one or more Customer Lists, with an optional segment that limits the Newsletter to a subset of subscribers on those lists.

Response Body

Then endpoint returns an object with a data key that the Newsletter object. The included info:

Key

Details

id:

string

The Newsletter’s ID. Use it when calling single-newsletter endpoints.

title:

string

The Newsletter’s title.

audience

object

The Newsletter’s audience. Can be comprised of one or more lists, a segment ID or an inline segment. See above.

liveAt:

string, optional

When the Newsletter is set to go live, if scheduled, or when it was set live, if sent or live. Is an ISO 8601 encoded date. Is omitted if the Newsletter is a draft.

status:

string

The Newsletter’s current status. Must be one of “draft”, “scheduled”, “live”, or “sent”.

sentAt:

string, optional

When the Newsletter was fully sent, if such is the case. Is an ISO 8601 encoded date.

stats:

object

An object with this Newsletter’s stats. Included keys are described below.

contentModules:

array

An array of the Content Modules in a Newsletter. These represent the content (copy, images, discounts, etc.) in a Newsletter. More details below.

customerLists (deprecated):

string[]

An array of IDs of Customer Lists who will receive / have received this Newsletter. May be empty. Deprecated in favour of audience.

customerSegments (deprecated):

string[]

An array of IDs of Customer Segments who will receive / have received this Newsletter. May be empty. Deprecated in favour of audience.

Stats

The stats key has the following format:

Key

Details

sends:

number

The total number of emails that were sent for this Newsletter.

opens:

number

The total number of times this Newsletter’s emails have been opened.

uniqueOpens:

number

The number of unique users that have opened this Newsletter’s emails.

clicks:

number

The total number of clicks on this Newsletter’s links.

recipientCount:

number

How many recipients was this Newsletter sent to. May differ from sends if there are sending errors.

Content Modules

{"contentModules":[{"position":0,"type":"text","context":{"body":"Black Friday Sale!"}},{"position":1,"type":"image","context":{"value":"https://www.epic-store.com/black-friday-img.png","url":"https://www.epic-store.com/sale","alignment":"center"}},{"position":2,"type":"discountCoupon","context":{"title":"Extra Black Friday Discount","description":"{{firstName}}, these are the last few hours of our Black Friday sale! As an extra incentive, this is a coupon for extra {{discount}} off your next purchase :)","actionTitle":"Start Shopping","expiresOn":"Expires On","primaryColor":"#1990FF","amount":10,"expiryPeriod":1,"emailLimit":false,"couponType":2,"backgroundColor":"#f8f8f8","onePerUser":true,"usageLimit":1}}]}

Each module has a position and a type. The 0-based position indicates where in the Newsletter the module appears (starting from top) and the type defines the kind of content.

The module’s content is in the context key. This object and its keys depend on the module’s type. These map directly to the content & settings in the Newsletter editor, so we recommend referencing that in case any values are unclear.

List Newsletter Emails

A paginated list of all the emails sent for a Newsletter. Will be empty if Newsletter has not been sent yet. Emails are returned sorted by email address, and pagination is done by providing the email address from which to return results.

Note that if the Newsletter is currently live and sending, paginating results will not guarantee that all emails are returned. Wait for the “sent” status if an exhaustive list is required.

{"data":{"id":"57b5aa3b046abfb053d80b68","to":"a@customer.com","sentAt":"2016-11-20T00:00:00.000Z","deliveredAt":"2016-11-20T00:00:15.000Z","openedAt":"2016-11-20T01:00:00.000Z","clickedAt":"2016-11-20T01:01:10.000Z","rendered":{"text":"This is an email's text version...","html":"<html><body>This is an email's HTML content...</body></html>","subject:":"This is the Newsletter's subject."}}}

Arguments

Return

The endpoint returns an object with a data key with the found subscribers, and a meta key with pagination info. By default, the returned subscribers are Customer objects with event & stats data.

However, when querying for pending or unsubscribers the returned subscribers include only the email key. Pagination is also different. This is for legacy reasons and is likely to change (to match the default return) in the future.

To ensure your app supports all returns and is future-proof, expect only the email address in the return, and use nextPage for pagination.

Key

Details

email:

string

The email address for the subscriber. Only common field across all queries.

Response 200

Mass Unsubscribe

Removes one or more list’s subscribers. There are two versions of this request: one that removes a list of emails, another that removes a whole segment.

Unsubscribe via Customer Segment [DELETE]

Arguments

These are provided via query params.

Key

Details

segment:

string[]

A Customer Segment in JSON format.

Return

There are two possible return formats: If the number of subscribers to remove is relatively low, they will be removed synchronously with the request and the return will mirror the Unsubscribe via Email List’s. Otherwise, an Async Job is started and it’s ID returned instead inside the data key.

The following format is returned only with status 202:

Key

Details

asyncJobId:

string

An Async Job’s ID.

Response 200 - Subscribers removed synchronously

Response 202 - An async job was created to complete the mass unsubscribe

Create Export Job [POST]

Response 404 - Customer Segment not found. One of the following happened:

The given ID does not belong to an existing Customer Segment

The ID belongs to another shop’s Customer Segment

The Customer Segment has been deleted

Response Body

The response body includes a data key which reflects the created Async Job’s info:

Key

Details

id:

string

The ID for the created AsyncJob. Use this to identify this export.

kind:

string

The kind of job created. Is always segments-export on this endpoint.

status:

string

The job’s status. Always pending.

Webhooks

Endpoints for subscribing and configuring Webhooks triggered by events on your account.

You should use webhooks to get near real-time updates on events in a shop. When one of the supported events happens (eg: a newsletter email is sent), Conversio will POST some data related to that event to the endpoints registered in webhooks that subscribed to that event’s topic.

When Webhook delivery fails (your endpoint can’t be reached or returns an error status code), we’ll keep trying to re-send the failed Webhooks up to a limited number of tries, in an exponential back-off fashion. Details are described below.

For security purposes, all our webhooks use JSON Web Signatures (JWS). These allow recipients to validate that each webhook originates from Conversio. More details on the validation are below.

Subscribable Topics

newsletter-template/sent: Triggered when all emails for a Newsletter have been sent.

newsletter-email/sent: Triggered when a Newsletter is sent to a customer. These typically arrive in bursts as the Newsletter Template is sending;

async-job/completed: Triggered when an Async Job has been completed (failed or succeeded).

abandoned-cart-email/sent: Triggered when an email was sent for an Abandoned Cart.

Payload

All request bodies contain two keys, meta and data. The meta key contains information about the webhook itself:

Key

Details

topic:

string

The Webhook’s topic. Useful if you wish to direct all webhooks to the same endpoint.

ts:

number

The timestamp for when the webhook was first sent. This will stay equal for subsequent retries.

The data key’s content depends on the Webhook’s topic. The following apply:

The email address of the customer that received this email (also the owner of the Abandoned Cart).

status:

string

The email’s status. Is “sent”.

sentAt:

stringl

When the email was sent. Is an ISO 8601 encoded date.

subject:

string

The email subject.

Retry Mechanism

Webhooks retry up to 6 times, for a total of 7 attempts. Multiple failures are grouped by endpoint and retried in batches. If 5% or more of a batch of retries fails consecutively, all webhooks in that batch are skipped and an attempt is counted for each.

List all Webhooks [GET]

https://app.conversio.com/api/v1/webhooks

OAuth Scopes: read_webhook, write_webhook

Response 200 (application/json)

Response Body

Then endpoint returns an object with a data key that is an Array with all the webhooks in the shop. It will limit output to the currently authenticated Partner App webhooks if authorized through OAuth.

Each webhook includes the following info:

Key

Details

id:

string

The Webhook ID. Use it when calling single-webhook endpoints.

topic:

string

The event that triggers this webhook.

endpoint:

string

Where the webhook’s payload is sent, when triggered. Must be a URI.

partnerApp:

string, optional

The ID of the Partner App that created this webhook. Included only when authorization is made with the API key.

Async Jobs

An Async Job is created on certain API endpoints and user actions that we expect will take a long time to complete. Generally, when a job is created, you’ll receive a Job ID that you can poll using this API to:

Check if the job’s completed;

Get the job’s result; and

Check the job for errors.

Due to the presumably large size of an Async Job’s results and how they’ll be less relevant as time advances, Async jobs expire 1 week after they’ve finished processing, being automatically removed.

List Async Jobs

Returns all the Async Jobs created for the authenticated shop. When using OAuth, only jobs started by the authenticated app are returned.

{"data":[{"id":"57b5aa3b046abfb053d80b52","kind":"newsletter-recipients","status":"done","startedAt":"2017-01-03T16:32:27.741Z","completedAt":"2017-01-03T16:37:20.417Z","result":"https://app.conversio.com/async-jobs/57b5aa3b046abfb053d80b52.csv"},{"id":"57b5aa3b046abfb053d80b54","kind":"newsletter-recipients","status":"pending"},{"id":"57b5aa3b046abfb053d80b57","kind":"newsletter-recipients","status":"failed","startedAt":"2017-01-02T05:33:22.123Z","completedAt":"2017-01-02T05:33:45.412Z","error":"Something terrible has happened. Get in touch with support tout de suite!"}]}

List all Jobs [GET]

https://app.conversio.com/api/v1/async-jobs

OAuth Scopes: read_async_job

Response 200 (application/json)

Response Body

The endpoint returns an object with a data key that is an Array with all the Async Jobs in the shop. It will limit output to the currently authenticated Partner App webhooks if authorized through OAuth.

Each Async Job includes the following info:

Key

Details

id:

string

The Async Job ID. Use it when calling single-job endpoints.

kind:

string

What kind of job this is. Currently only supports “newsletters-recipients”.

status:

string

The job’s status. One of “pending”, “done” or “failed”.

startedAt:

string, optional

When this job started processing. Is an ISO 8601 encoded date. Is null if it hasn’t started yet.

completedAt:

string, optional

When this job completed. Is null if it hasn’t finished yet. There’s a result or error if set. Is an ISO 8601 encoded date.

error:

string, optional

An error message that indicates a problem when processing the job. There is no result if this is present.

result:

string, optional

The final result from processing this job. Contents depend on job kind.

partnerApp:

string, optional

The ID of the Partner App that created this Async Job. Included only when authorization is made with the API key.

Get Async Job

Returns the requested Async Job. When using OAuth, only jobs started by the authenticated app can be accessed.

Response Body

The endpoint returns an object with a data key. The data key is an object with the Async Job’s properties. It will include the Partner App if authorized with an API key. The following keys are returned:

Key

Details

id:

string

The Async Job’s ID. The ID used to call this endpoint.

kind:

string

What kind of job this is. Currently only supports “newsletters-recipients”.

status:

string

The job’s status. One of “pending”, “done” or “failed”.

startedAt:

string, optional

When this job started processing. Is an ISO 8601 encoded date. Is null if it hasn’t started yet.

completedAt:

string, optional

When this job completed. Is null if it hasn’t finished yet. There’s a result or error if set. Is an ISO 8601 encoded date.

error:

string, optional

An error message that indicates a problem when processing the job. There is no result if this is present.

result:

string, optional

The final result from processing this job. Contents depend on job kind.

partnerApp:

string, optional

The ID of the Partner App that created this Async Job. Included only when authorization is made with the API key.

Partner Apps API

This API comprises of management endpoints for Partner Apps. Because they’re unrelated to any Store, authentication is done through HMAC.