Skip to content

openbridge/embedded-api

Repository files navigation

Openbridge API Documentation

Welcome to the Openbridge API documentation. This guide is designed to help developers understand, integrate, and embed the Openbridge API into their applications. Included are detailed information and examples here if you're looking to access specific data, manage identities, or handle authorizations.

Getting Started

How do I get access to Openbridge APIs?

To get access to use the Openbridge APIs requires a discussion with the Openbridge support. Please contact us via the official support portal to request access.

API User Role

Customers who have been granted access to use the Openbridge APIs will be given the api-user role to the owner of the account. Once Openbridge support has said that this role has been added to your account you will need to log out of the Openbridge app and then log back in. This updates any cached token in the browser with a new one with the required permissions to generate a refresh token for your account.

Refresh Token

A refresh token is a long lived token that your application will use to generate a JWT using the Openbridge authorization API. To create a refresh token you must have been granted the api-user role on your account. If you have this role, log into the Openbridge app. In the main menu and select Account and you will be presented with a API Management menu option to navigate you to the refresh token management page. Click on the "Create Refresh Token" button. A modal will present itself where you will need to choose a name for the token. Click the Create button and your token will be generated, and presented to you. It is VERY IMPORTANT that you copy this token and store it in a text file, or in your application preferences/settings. As a security precaution we will not present this token to you again, as it is not stored in a way we can present it to you again. If you lose your token you will be required to generate a new one.

Understanding Openbridge data collection

Before you start integrating with Openbridge's API it is important that you understand how Openbridge collects data from third-party APIs for our customers.

Destinations

Before you can start collecting data through Openbridge you must have configured a destination. A destination is the location where Openbridge will store the collected data. Our Destination FAQ for more specific information on destinations. Destinations can only be configured through the Openbridge app, we currently do not support destination configuration through the API.

Remote Identities.

Openbridge connects to third-party data sources on the behalf of our customers using credentials granted to us by the customers through the third-party API's chosen authentication method. In most cases this is through industry standard Oauth protocol. We call these grants Remote Identities (sometimes referred to as Identities). In some cases a Remote Identity grant does not expire, and once you create a pipeline attached to an identity that pipeline will collect data until the customer disables it. In other cases a Remote Identity need to be re-authorized periodically. Facebook for example requires that authorizations be re-authorized every 90 days. Openbridge has made the process of authorizing and reauthorizing a remote identity easy to managed. Our article on "Understanding Remote Identities" provides a in depth understanding of how to manage remote identities and key dos and don'ts.

Currently support for authorizing identities through our API for all products except for Shopify which requires a more complex process than defined in "Identity Authorization".

Source Pipelines

A source pipeline defines what third-party data will be retrieved for the customer. Some sources require more information to configure than others. (some additional text here about how to learn what is what.). For a better understanding of what specific data a specific source provides please check out one of our many articles on data sources.

Identity Authorization

Openbridge call authorizations we have made to third party vendors identities. In most cases these third party authorizations are created through the third party's Oauth service. Openbridge has created our own API that manages redirecting a user to these APIs and on a successful authorization a return to a specific return_url with some included meta data stored in the query string. In most cases on an error the user is also redirected back to the return_url with some meta data that specifies the error condition. However due to the way some of the third party APIs handle errors, sometimes a user can result in being dead ended at on a page hosted by the third party. There is unfortunately nothing that can be done in those cases, but to document it.

Creating your first identity

Identity State

The first step in creating an identity is to create a persistent state using the Openbridge state api. The OAuth standard has us pass a state token at the beginning of the process. This allows us to retain the state from the beginning of the process through the end of the process as on the return the state token is given back to us.

The schema for the state to create an identity is:

 {
    account_id: string;
    user_id: string;,
    region: string;
    remote_identity_type_id: integer;
    return_url: string;
    shop_url: string | null;
   }

The account_id and the user_id can be retrieved using the Account API. The account_id will be the data.id on the response tree, and the user_id will be data.attributes.owner.id on the response tree.

Identity Types


Openbridge offers connections to several third parties. Internally we call these remote identity types and we have an id that we associate with each of them.

id provider region
1 Google (except for Adwords) global
2 Facebook global
8 Google Adwords global
14 Amazon Advertising region index
17 Amazon Selling Partner region index
18 Amazon Vendor Central region index

Amazon Advertising Regions


region identifier region name
na North America
eu Europe
fe Far East

Amazon Selling Partner & Vendor Central Regions


region identifier region name
AU Australia
BR Brazil
CA Canada'
EG Egypt
FR France
DE Germany
IN India
IT Italy
JP Japan
MX Mexico
NL Netherlands
PL Poland
SA Saudi Arabia
SG Singapore
ES Spain
SE Sweden
TR Turkey
UK United Kingdom
AE United Arab Emirates (U.A.E.)
US United States

Redirect URL

Whether the identity is created successfully, or an error happens in the process, the oauth API needs to know where to return the end user too. We store this in the state, it allows for greater flexibility in app creation, since you aren't tied to returning a user to a single location. Openbridge for example redirects users to the wizard they started on. We include a parameter to indicate what stage of the wizard the user was last on.

Shop URL

The shop_url is only used in conjunction with shopify identities. Currently we do not support the creation of Shopify authenticated identities for our API users at this time.

Create your first state object

With these in mind, let's create a state that can be used for gaining an authorization for Amazon Selling Partner API, We'll do it for account 1, that is owned by user 1. (Don't really do this it is only for example, please use your own user and account id, you can use the Account API to retrieve them.). We will do it for the US region. We'll then return them to the Openbirdge wizard for the Selling Partners "Orders API" product, and we'll pass the stage parameter so we land on the identity selection page.

{
 "account_id": "1";
 "user_id": "1";,
 "remote_identity_type_id": 17;
 "region": "US;
 "return_url": "https://app.openbridge.com/wizards/amazon-selling-partner-orders?stage=identity"
 "shop_url": null;
}
{
  "account_id": "1",
  "user_id": "1",
  "remote_identity_type_id": 17,
  "region": "US,
  "return_url": "https://app.openbridge.com/wizards/amazon-selling-partner-orders?stage=identity",
  "shop_url": null
}

Now that we have the state object, we need to generate a payload for the state API with it. We add it to the payload as the state attribute.

{
  "data": {
    "type": "ClientState",
    "attributes": {
      "state": {
        "account_id": "1",
        "user_id": "1",
        "remote_identity_type_id": 17,
        "region": "US",
        "return_url": "https://app.openbridge.com/wizards/amazon-selling-partner-orders?stage=identity",
        "shop_url": null
      }
    }
  }
}

Our curl request for testing looks like this.

curl -H "Content-Type: application/json" -X POST -d '{ "data": { "type": "ClientState", "attributes": { "state": { "account_id": "1", "user_id": "1", "remote_identity_type_id": 17, "region": "US", "return_url": "https://app.openbridge.com/wizards/amazon-selling-partner-orders?stage=identity", "shop_url": null } } } }' https://state.api.openbridge.io/state/oauth

Which will produce the following response

{
  "data": {
    "type": "ClientState",
    "id": "36613eebc2b09e4ec36663ebdf647658",
    "attributes": {
      "token": "36613eebc2b09e4ec36663ebdf647658",
      "created_at": "2023-01-26T14:29:09.996295",
      "modified_at": "2023-01-26T14:29:09.996327",
      "state": {
        "account_id": "1",
        "user_id": "1",
        "remote_identity_type_id": 17,
        "region": "US",
        "return_url": "https://app.openbridge.com/wizards/amazon-selling-partner-orders?stage=identity",
        "shop_url": null
      }
    }
  }
}

You can see that the output is much like the input, except we have been given created_at and modified_at data, and the id and token which should always be the same thing. What we really care about is the id/token. This is the value that will represent our calls to the third-party OAuth APIs.

Starting the authorization process


To start the authorization process simply redirect the user in the browser to the Oauth API's initialize URL along with the state token.

https://oauth.api.openbridge.io/oauth/initialize?state=XXXXXXXXXXXXXXXXXXXXXXXXXXXX

Security Note (MUST READ).

The OAuth API is called via a redirect in the browser. It should NEVER be called in a frame or iframe element withing HTML in the browser. Many OAuth providers disable this as it is a clickjacking security risk. All of the providers Openbridge uses have disabled it. Popups may work on some third parties, but it is not supported by Openbridge.

Once the user is directed to the Openbridge Oauth api, the state is read based on the passed in state token. Based on the remote_identity_type_id in the state the end user will be redirected to the correct oauth provider. In our example that is Amazon Selling Partner. Once the user completes the process they are returned back to the Openbridge oauth api, where the identity information is stored in the Openbridge database, and the end user is then redirected to the return_url that was created in the state. In our case the blow URL along with some additional query string parameters.

https://app.openbridge.com/wizards/amazon-selling-partner-orders?stage=identity&state=XXXXXXXXXXXXXXXXXXXXXXXXXXXX

Additional Oauth return parameters


key datatype description
state string The state id/token we passed during the initialization process.
ri_id integer The id of the created/reauthorized identity.
reauth boolean Whether this is a new identity in the Openbridge database or a reauthorization of an existing identity identity. An identity can be new to a user/account but not to our database. It is possible for 2 accounts to have the same identity associated with it. We call these shared identities.
status string returned when an error is present, it's value should always be error.
status_message string The message related to the status, in this case it is an error message.

In the case of the status key, you should check for the value to be error, as in the future this field may be expanded on. Don't rely simply on it's existence for error handling.

When an identity is successfully created you can use the identities API to query it.

Note The process for reauthorizing an identity is exactly the same as creating one. In the case of a reauth we return parameter reauth in the querystring.

Pipeline Subscription Configuration

Create Pipeline Subscription

The process for creating a pipeline subscription is similar for every openbridge product. Most products require an asscociated identity record. Most products also require some information from third party APIs such as Amazon or Facebook. This is why our wizards will always ask for them in that order.

The first step is to decide which product you want to create a pipeline subscription for. We provide Comprehensive List of products and their associated attributes for this reason.

Some products require information from a third-party API, and others do not. This needs to be taken into consideration when building a system to create pipeline subscriptions.

An example of a product that doesn't require third-party API calls is the Amazon Orders API product. The reason for this is that Seller Central Identities are a one-to-one relationship with the Amazon Seller account.

An example of a product that does require a third-party API call would be Amazon Sponsored Brands. The reason for this is that Amazon Advertising identities are a one-to-many relationship. You can have many profiles for one Amazon Advertising Account authentication. Which means that in order for Openbridge to process data we'd need to know what account profiles to process the data.

Let's build out the payloads for the 2 above products to see how it's done. We'll need the Subscription API documentation for reference and grab the base payload.

{
  data: {
    type: string,
    attributes: {
      account: integer,
      user: integer,
      product: integer,
      name: string,
      status: string,
      subscription_product_meta_attributes: array,
      remote_identity_id: integer,
      unique_hash: string,
      storage_group: integer,
      quantity: integer,
      price: double,
      auto_renew: integer,
      date_start: DatetimeString,
      date_end: DatetimeString,
      invalid_subscription: integer,
      rabbit_payload_successful: integer,
      stripe_subscription_id: string
    }
  }
}

Note: Some of the parameters are depricated but require, please reference the API documentation on what default values to set for these fields.

For the 2 examples we will set both account and user to the value of 1. This is the user id and account id the pipeline subscription will be associated with. Please make sure to use the user id and account id associated with your account and user, and we'll also set storage_group to 1 as that is going to be the storage group id for our subscriptions. The storage group is a reference destination that your data will be stored in. In order to get the storage_group_id associated with your destinatino you should first query the subscription API with the subscription ID of the subscription of your destination.

If the subscription ID for your destination was 1000, then you would do an HTTP get request for that subscription. Inside the payload is the storage_group_id. Use that for all sources that you want to go to this particular destination.

Example 1

We will create a payload to create a Orders API source pipeline. Referencing Amazon Orders API in the documentation we see this is product id 53.

We can also see that the Remote Identity Type ID is 17. Use the Remote Identity API to search for the identity you want to associate with your pipeline subscription. For this example we'll use identity id 1. You should use one assocated with your account.

We need to give it a unique name. The status must be defined as active (all lowercase characters).

Unique Hash should always be a string with the value of [].

Fields after unique_hash are deprecated fields. Reference the Payload Attribute Fields for their defaults.

{
  "data": {
    "type": "Subscription",
    "attributes": {
      "account": 1,
      "user": 1,
      "product": 53,
      "name": "My Orders API Subscription",
      "status": "active",
      "subscription_product_meta_attributes": [],
      "remote_identity_id": 1,
      "unique_hash": "[]",
      "storage_group": 1,
      "quantity": 1,
      "price": 0,
      "auto_renew": 1,
      "date_start": "2024-06-01 00:00:00",
      "date_end":  "2024-06-01 00:00:00",
      "invalid_subscription": 0,
      "rabbit_payload_successful": 0,
      "stripe_subscription_id": ""
    }
  }
}

subscription_product_meta_attributes is an array of meta attributes required for the subscription to be processed. It will contain an array of objects that with the below schema

{
  "data_key": string,
  "data_value": string,
  "data_format": string,
  "data_id": number,
}

Each product will have a different number of objects needed in this array, containing the different information required for them. In this case we can see from Amazon Orders API that we only need one with the remote identity ID.

{
  "data_key": "remote_identity_id",
  "data_value": "1",
  "data_format": "STRING",
  "data_id": "0",
}

Note: data_id will always be 0 as it is a deprecated field.

The final payload would look like this.

{
  "data": {
    "type": "Subscription",
    "attributes": {
      "account": 1,
      "user": 1,
      "product": 53,
      "name": "My Orders API Subscription",
      "status": "active",
      "subscription_product_meta_attributes": [
        {
          "data_key": "remote_identity_id",
          "data_value": "1",
          "data_format": "STRING",
          "data_id": "0",
        }        
      ],
      "remote_identity_id": 1,
      "unique_hash": "[]",
      "storage_group": 1,
      "quantity": 1,
      "price": 0,
      "auto_renew": 1,
      "date_start": "2024-06-01 00:00:00",
      "date_end":  "2024-06-01 00:00:00",
      "invalid_subscription": 0,
      "rabbit_payload_successful": 0,
      "stripe_subscription_id": ""
    }
  }
}

Example 2

We will create a payload to create a Amazon Advertising Sponsored Ads (v3) source pipeline. Referencing Amazon Orders API in the documentation we see this is product id 70.

We can also see that the Remote Identity Type ID is 14. Use the Remote Identity API to search for the identity you want to associate with your pipeline subscription. For this example we'll use identity id 2. You should use one assocated with your account.

Following what we did for Example 1 will give us the following base payload.

{
  "data": {
    "type": "Subscription",
    "attributes": {
      "account": 1,
      "user": 1,
      "product": 70,
      "name": "My Sponsored Ads V3 Subscription",
      "status": "active",
      "subscription_product_meta_attributes": [
      ],
      "remote_identity_id": 2,
      "unique_hash": "[]",
      "storage_group": 1,
      "quantity": 1,
      "price": 0,
      "auto_renew": 1,
      "date_start": "2024-06-01 00:00:00",
      "date_end":  "2024-06-01 00:00:00",
      "invalid_subscription": 0,
      "rabbit_payload_successful": 0,
      "stripe_subscription_id": ""
    }
  }
}

Now to build out the meta attributes in Sponsored Ads (v3) section. You will see that we need a remote_identity_id and a profile_id which is an Amazon Advertising profile id.

Sponsored Ads (v3) has instructions and links to the API documentation on what endpoint to use to get this value.

Pausing / Cancelling Subscription Pipeline.

If you want to turn off a pipeline either permentantly or temporarily you need change the status of the record on file. This is done with a patch request. Through the Subscription API and is described in our API documentation.

Deleting Subscription Pipeline.

Pipeline Subscriptions are not deletable through the API. Nor are they deletable through the Openbridge App. Instead you must use the PATCH functionality to mark their status as invalid. Once they are marked as invalid you will no longer see them in the Openbridge app interface. Pipeline subscriptions marked as invalid can be set to active or cancelled as long as there are no duplicate subscriptions that are in an active or cancelled status.

History Requests

After creating a pipeline subscription you may want to back fill past history into your database. This can be done with using the history API endpoints. There are 3 different endpoints that are linked to history requests. The first two provide meta data used in making the actual request. Those are the History Max Requests endpoint and the Product Payloads endpoint. Lastly there is the endpoint for making the request History Request endpoint.

Basic History Request.

Making a basic history requests uses 2 of the 3 endpoints. The History Max Requests endpoint and the History Request endpoint.

The purpose of the History Max Request endpoint is to provide details reguarding how far back in the past you can go to request. This data contains a list for all products, and is slow changing. Since it is slow changing, this is an example of a request that the data could be cached locally for short periods of time. We recommend not caching it for more than 24hrs at a time.

Using the request below along with your authorizatino token you will be given a list of all Openbridge products that support history requests, along with meta data needed to make those history requests.

curl -H "Content-Type: application/json" -H "authorization: Bearer YOURJWTXXXXXXXXXXXX" -X GET https://service.api.openbridge.io/service/history/production/history/meta/max-request

The response will be an array of product history meta data like below.

{
"data": [
{
 "id": 57,
 "attributes": {
 "max_request_time": 90,
 "max_days_per_request": 88,
 "base_request_start": 2
 }
},
 ...
]
}

Take the example above for product 57. There are 3 meta attributes. The first is max_request_time. The value to this key is the maximum number of days you can request history for. The second max_days_per_request is the maximum number of days you can request history for per request. Lastly base_request_start is the offset in days from the time the request is being made that history can not be requested for.

Example. You have a subscription for product 57. Today is May 1st 2024. Since this product has a base_request_start of 2 it means that start_date in the history request can be no sooner than 2 days in the past. Therefore, in this instance The start_date can be no sooner than April 29, 2024. With a max_request_time of 90 means that the end_date date in the history request can be no further back than 90 days. In our case 90 days before May 1st 2024 is February 1st 2024. This is the last date that we can request data for if requesting it on May 1st, 2024. This means you can request a maximum of 88 days worth of data.

Once you have calculated your start_date and your end_date you can build a payload for your history requeset. Using the above as our example our payload would look something like.

Note: All date should be calculated for UTC.

{
  "data": {
    "type": "HistoryTransaction",
    "attributes": {
      "start_date": "2024-04-29",
      "end_date": "2024-02-01"
     }
  }
}

The start_date is the date closest to the date you are making your request, and the end_date is the calculated date in the past X number of days, in our case 88 days.

Posting this payload to https://service.api.openbridge.io/service/history/production/history/{{subscriptionId}} with the subscription ID as a parameter will create the history request.

Advanced History Request.

There is sometimes specific data that you may want to prioritize being loaded first. The history request payload has 2 optional fields that must be used together when requesting these. stage_id and start_time.

To get a list of stage_ids for a given product you need to use the Product Payloads endpoint.

curl -H "Content-Type: application/json" -H "authorization: Bearer YOURJWTXXXXXXXXXXXX" -X GET  https://service.api.openbridge.io/service/products/product/{{product_id}}/payloads?stage_id__gte=1000

Making a request to this endpoint will give you a list of stages for a given product. Some products may have only 1 stage, some 10. Using our example for product 57.

{
  "links": {
    "first": "https://55anmbidzh.execute-api.us-east-1.amazonaws.com/product/57/payloads?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-SHA256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855&X-Amz-Credential=ASIAVIA2REQV3GMWZ76G%2F20240508%2Fus-east-1%2Fexecute-api%2Faws4_request&X-Amz-Date=20240508T132023Z&X-Amz-Expires=300&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEJT%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMSJGMEQCIBaDZdHncY%2FxMZm1mUMmR2hxr4j9YepYeqb8EcTOXOM8AiAZc%2FdNPaXzuy5WQTxaqp5M5Tiaabg%2FpwKuHBMmsx787ir7Agjt%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8BEAAaDDM2MDgzMjkwMjE4NyIMjGVeYVqEeH5RgvvtKs8CZKysCemifK0yFjaBQDoUB1vRwGfhV5qb9iCtQ2rF9ruoho%2FlViIZHIHeqd9uV%2BMEChB7kTa9%2Bi5UR%2B5xu4YQQL6el6dcz6%2Fn6mNtQIrtqZMVFWrB6c68u%2BYh3ggUKnx6UZSdU0zWkCQJ7%2BCWZI1q8Q3%2BUyMv6j4WdANf9tzfDGCQ7yxdbkBRS8JcrgQ8sfBOBXmhcIHGlHYma1dQRGPDOxAaxshEEgoQWgr3y6CZ3NKHJq0UssKqmsPO7cQIzvvrxZU2wiEApWx8ABNtRcv0cgNUqclvGKiCI0rknkv6jdCK%2BYk4Q%2BmPpxEPr8G0ZoqImD4QhkpPgtA1Iv17aFrwSZ0%2Fgm457yo5KY9zw1gqauEf1TErx3vJjSDyzT%2FUewT0wn%2BNbLtej2vdGBSEQubuooCFu8bBU1xk%2BPz8ePU3P0skVUBcvgUU%2FX44JQod4Nswqc3tsQY6nwFli4si8b1ZOl0Cnc9xMmGZYt8gytcPAir9890jXFAfoz4t4yPyNMZ0eJu%2BUOc1t7yHOGXFL2SvIsvgWA00bBLPIXyMb4IYqXygGWguni1nnr72Gn%2BmG7tMzZGYt4PIwNby%2FSAUCEzEDnpfpztvZ3Bls%2FeGHOmLx%2FcI%2FP0GR8zIk7MpocVvtNiKuv0AJwfZIUX69uZwmfc1320Yu4ZGh1E%3D&X-Amz-Signature=b6b1759feb329196244134b9acfb5bef944f951aa1771243a9ac989b6411d18d&X-Amz-SignedHeaders=host&page=1&stage_id__gte=1000",
    "last": "https://55anmbidzh.execute-api.us-east-1.amazonaws.com/product/57/payloads?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-SHA256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855&X-Amz-Credential=ASIAVIA2REQV3GMWZ76G%2F20240508%2Fus-east-1%2Fexecute-api%2Faws4_request&X-Amz-Date=20240508T132023Z&X-Amz-Expires=300&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEJT%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMSJGMEQCIBaDZdHncY%2FxMZm1mUMmR2hxr4j9YepYeqb8EcTOXOM8AiAZc%2FdNPaXzuy5WQTxaqp5M5Tiaabg%2FpwKuHBMmsx787ir7Agjt%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8BEAAaDDM2MDgzMjkwMjE4NyIMjGVeYVqEeH5RgvvtKs8CZKysCemifK0yFjaBQDoUB1vRwGfhV5qb9iCtQ2rF9ruoho%2FlViIZHIHeqd9uV%2BMEChB7kTa9%2Bi5UR%2B5xu4YQQL6el6dcz6%2Fn6mNtQIrtqZMVFWrB6c68u%2BYh3ggUKnx6UZSdU0zWkCQJ7%2BCWZI1q8Q3%2BUyMv6j4WdANf9tzfDGCQ7yxdbkBRS8JcrgQ8sfBOBXmhcIHGlHYma1dQRGPDOxAaxshEEgoQWgr3y6CZ3NKHJq0UssKqmsPO7cQIzvvrxZU2wiEApWx8ABNtRcv0cgNUqclvGKiCI0rknkv6jdCK%2BYk4Q%2BmPpxEPr8G0ZoqImD4QhkpPgtA1Iv17aFrwSZ0%2Fgm457yo5KY9zw1gqauEf1TErx3vJjSDyzT%2FUewT0wn%2BNbLtej2vdGBSEQubuooCFu8bBU1xk%2BPz8ePU3P0skVUBcvgUU%2FX44JQod4Nswqc3tsQY6nwFli4si8b1ZOl0Cnc9xMmGZYt8gytcPAir9890jXFAfoz4t4yPyNMZ0eJu%2BUOc1t7yHOGXFL2SvIsvgWA00bBLPIXyMb4IYqXygGWguni1nnr72Gn%2BmG7tMzZGYt4PIwNby%2FSAUCEzEDnpfpztvZ3Bls%2FeGHOmLx%2FcI%2FP0GR8zIk7MpocVvtNiKuv0AJwfZIUX69uZwmfc1320Yu4ZGh1E%3D&X-Amz-Signature=b6b1759feb329196244134b9acfb5bef944f951aa1771243a9ac989b6411d18d&X-Amz-SignedHeaders=host&page=1&stage_id__gte=1000",
    "next": "",
    "prev": ""
  },
  "data": [
    {
      "type": "Product",
      "id": "2958",
      "attributes": {
        "name": "sp_settlements",
        "created_at": "2024-05-03T13:36:40.156426",
        "modified_at": "2024-05-03T13:36:40.185841",
        "stage_id": 1000
      }
    }
  ],
  "meta": {
    "pagination": {
      "page": 1,
      "pages": 1,
      "count": 1
    }
  }

Product 57 only has one stage called sp_settlments. Generally, it is not necessary to make an advanced history request when the product only has one stage, but for example simplicity we will mock one for this product. Taking our payload from the basic history request above we will add the 2 fields needed. The datetime must be a date in the future at least 15 minutes after the time of submission for history request.

{
  "data": {
    "type": "HistoryTransaction",
    "attributes": {
      "start_date": "2024-04-29",
      "end_date": "2024-02-01",
      "stage_id": 1000,
      "start_time": "2024-04-29 00:00:00"
    }
  }
}

Note: All date and datetime fields should be calculated for UTC.

APIs

Deprecated key-value pairs in requests and response

In the API you will see note to items that are marked as deprecated. You will be required to include many of them as inputs to POST functionality, and receive them as part of the output, but you should not rely on the output in the future, as they will be removed in the future.

Authorization API

POST https://authentication.api.openbridge.io/auth/api/ref
Responses
http code content-type response
202 application/json Accepted
Example cURL
curl --request POST -d '{"data": {"type": "APIAuth","attributes": {"refresh_token": "REFRESH_TOKEN"}}}' https://authentication.api.openbridge.io/auth/api/ref
Example Response
{
  "data": {
    "attributes": {
      "token": "eyXXXXXXXXXXXXXXXXXXXXX",
      "expires_at": 1674576819.8652437
    }
  }
}

Account API

The Openbridge Account API is a RESTFUL API, that supports. GET, POST and PATCH methods. However, while the API supports all of these methods, Openbridge customers with the api-user role are current restricted to only the GET method. The reason is that their account and user IDs are prerequisites for many other Openbridge APIs therefore we provide GET functionality on the account API to fulfill those requisites.

A prerequisite to using the Account API is to create a Openbridge JWT using your account refresh token.

GET https://account.api.openbridge.io/account
Headers
name data type description
Authorization string Openbridge JWT, passed as a authorization bearer type
Parameters

The GET method does not require any parameters. Parameters are based on credentials supplied in the JWT.

Responses
http code content-type response
200 application/json Configuration created successfully
Example cURL
 curl -X GET -H "Content-Type: application/json" -H "authorization: Bearer YOURJWTXXXXXXXXXXXX" https://account.api.openbridge.io/account
Example Response
{
 "links": {
   "first": "https://account.api.openbridge.io/account?page=1",
   "last": "https://account.api.openbridge.io/account?page=1",
   "next": "",
   "prev": ""
 },
 "data": [
   {
     "type": "Account",
     "id": "XXXXX",
     "attributes": {
       "account_status": 1,
       "stripe_customer_id": "cus_XXXXXXXXXXXX",
       "company": "",
       "created_at": "20XX-XX-XXTXX:XX:XX",
       "modified_at": "20XX-XX-XXTXX:XX:XX",
       "free_subscription_limit": 0,
       "free_subscriptions": 0,
       "is_branded": 0,
       "stripe_subscription_id": "sub_XXXXXXXXXXXX",
       "in_trial": 1,
       "renews_at_period_end": 0,
       "period_ends_at": "20XX-XX-XXTXX:XX:XX",
       "deactivate_at": "20XX-XX-XXTXX:XX:XX",
       "account_type_id": 13,
       "country_id": null,
       "primary_account_address_id": null,
       "primary_account_card_id": null,
       "extended_trial": 0,
       "organization_id": null,
       "organization_allowed": false,
       "owner": {
         "id": "YYYY",
         "auth0_user_id": "auth0|>636a4261738c1d3f4d57ae6f"
       }
     }
   }
 ],
 "meta": {
   "pagination": {
     "page": 1,
     "pages": 1,
     "count": 1
   }
 }
>}

From the example response, the accountId is data.id and the userId is data.attributes.owner.id

Remote Identity API

The Openbridge Remote Identity API is a RESTFUL API, that supports. GET, and POST methods. However, while the API supports all of these methods, Openbridge customers with the api-user role are current restricted to only the GET method. Allowing a means to look up state of an identity. Identity creation is handled through the Oauth API.

GET https://remote-identity.api.openbridge.io/ri/{id}
Headers
name data type description
Authorization string Openbridge JWT, passed as a authorization bearer type
Parameters

The GET method does not require any parameters. Parameters are based on credentials supplied in the JWT.

Responses
http code content-type response
200 application/json Configuration created successfully
Example cURL
curl -X GET -H "Content-Type: application/json" -H "authorization: Bearer YOURJWTXXXXXXXXXXXX" https://remote-identity.api.openbridge.io/ri/{remite_identity_id}

The /sri endpoint is used to return a list of all identities that your account has permissions to use. sri stands for shared remote identities. Since there is a chance that an identity can be shared between multiple Openbridge accounts we provide an endpoint to all identities associated to your account, even if it was created by another account previously.

Example Response

Returns an array of Remote Identities

[{
  "data": {
    "type": "RemoteIdentity",
    "id": "362",
    "attributes": {
      "name": "James Andrews",
      "created_at": "2018-02-13T18:49:51",
      "modified_at": "2022-10-26T20:43:21",
      "identity_hash": "b1e68ff9dca4539522c93f37ff3b9245",
      "remote_unique_id": "526589612",
      "account_id": 1,
      "user_id": 1,
      "notified_at": null,
      "invalidate_manually": 0,
      "invalid_identity": 0,
      "invalidated_at": "2019-05-11T00:05:01",
      "notification_counter": 0,
      "region": "global",
      "email": "thenetimp+facebook@gmail.com",
      "oauth_id": null
    },
    "relationships": {
      "remote_identity_type": {
        "data": {
          "type": "RemoteIdentityType",
          "id": "2"
        }
      },
      "account": {
        "data": {
          "type": "Account",
          "id": "1"
        }
      },
      "user": {
        "data": {
          "type": "User",
          "id": "1"
        }
      },
      "trusted_identity": {
        "data": null
      },
      "remote_identity_type_application": {
        "data": {
          "type": "RemoteIdentityTypeApplication",
          "id": "8"
        }
      },
      "oauth": {
        "data": null
      }
    }
  }
}]

Understanding the response fields

Attribute Fields
key data type description
name string ``
created_at string ``
modified_at string ``
identity_hash string deprecated
remote_unique_id string identifying value from the remote third party Oauth API
account_id string The id of the account that first created the identity
user_id string The id of the user that first created the identity
notified_at string The datetime of the last time the account/user was notified the identity credentials had become invalid.
invalidate_manually string deprecated
invalid_identity boolean If the identity credentials are currently valid
invalidated_at string The datetime that the identity became invalid
notification_counter string deprecated
region string The region associated with the identity
email string The email address associated with the profile by the third party (if available)
oauth_id string Association to an Oauth client/id secret for products that require user provided apps, such as Shopify.
Relationship Fields.
key data type description
remote_identity_type object Reference to the remote identity type
account object reference to the account
user object reference to the user
trusted_identity object deprecated
remote_identity_type_application object reference to an internal auth application
oauth object Association to an Oauth client/id secret for products that require user provided apps, such as Shopify.

Note: Identity credentials are not provided via the Remote Identity API

GET https://remote-identity.api.openbridge.io/sri
Headers
name data type description
Authorization string Openbridge JWT, passed as a authorization bearer type
Parameters

The GET method does not require any parameters. Parameters are based on credentials supplied in the JWT.

Responses
http code content-type response
200 application/json Configuration created successfully
Example cURL
 curl -X GET -H "Content-Type: application/json" -H "authorization: Bearer YOURJWTXXXXXXXXXXXX" https://remote-identity.api.openbridge.io/identity/{id}
Example Response
{
  "data": {
    "type": "RemoteIdentity",
    "id": "362",
    "attributes": {
      "name": "James Andrews",
      "created_at": "2018-02-13T18:49:51",
      "modified_at": "2022-10-26T20:43:21",
      "identity_hash": "b1e68ff9dca4539522c93f37ff3b9245",
      "remote_unique_id": "526589612",
      "account_id": 1,
      "user_id": 1,
      "notified_at": null,
      "invalidate_manually": 0,
      "invalid_identity": 0,
      "invalidated_at": "2019-05-11T00:05:01",
      "notification_counter": 0,
      "region": "global",
      "email": "thenetimp+facebook@gmail.com",
      "oauth_id": null
    },
    "relationships": {
      "remote_identity_type": {
        "data": {
          "type": "RemoteIdentityType",
          "id": "2"
        }
      },
      "account": {
        "data": {
          "type": "Account",
          "id": "1"
        }
      },
      "user": {
        "data": {
          "type": "User",
          "id": "1"
        }
      },
      "trusted_identity": {
        "data": null
      },
      "remote_identity_type_application": {
        "data": {
          "type": "RemoteIdentityTypeApplication",
          "id": "8"
        }
      },
      "oauth": {
        "data": null
      }
    }
  }
}

Understanding the response fields

Attribute Fields

These are the same as on a call to a single remote identity.

Relationship Fields.

These are the same as on a call to a single remote identity.

Note: Identity credentials are not provided via the Remote Identity API

DELETE https://remote-identity.api.openbridge.io/ri/{id}
Headers
name data type description
Authorization string Openbridge JWT, passed as a authorization bearer type
Parameters

The DELETE method requires the remote identity ID as part of the reuqest string.

Identities can be shared between more than one Openbridge account. The DELETE call will remove any association between the calling account and the identity. If the identity only belongs to the one account it will also delete the identity and any credentials associated with it.

Responses
http code content-type response
200 application/json Configuration created successfully
404 application/json Not found
Example cURL
curl -X DELETE -H "Content-Type: application/json" -H "authorization: Bearer YOURJWTXXXXXXXXXXXX" https://remote-identity.api.openbridge.io/ri/{remite_identity_id}

Subscription API

The Openbridge Subscription API is a RESTFUL API, that supports. GET, POST, and PATCH methods. It is used for creating, retrieving, and updating pipeline subscriptions.

POST https://subscriptions.api.openbridge.io/sub

The payload schema for creating a Pipeline Subscription is variant on the product associated with the pipeline.

Payload Schema.
{
  data: {
    type: string,
    attributes: {
      account: integer,
      user: integer,
      product: integer,
      name: string,
      status: string,
      subscription_product_meta_attributes: array,
      storage_group: integer
      quantity: integer,
      price: double,
      auto_renew: integer,
      date_start: DatetimeString,
      date_end: DatetimeString,
      invalid_subscription: integer,
      rabbit_payload_successful: integer,
      stripe_subscription_id: string
    }
  }
}
Payload Attribute Fields

Many of the fields below are deprecated, but must be passed into the payload to create a subscription. Please follow the informatino in description on how to set them properly.

key data type description
account string Account ID the subscription will belong to.
user string The user ID who created the pipeline
product string The product ID for the pipeline
name string The user defined name for the pipeline
status string The status of the pipeline. 'active', 'cancelled' or 'invalid'. An 'active' state indicates a pipeline subscription that is currently turned on., A 'cancelled' state means that pipeline subscription has been turned off. A 'cancelled' state means that pipeline subscription has been turned off. and can be reactivated by patching an 'active' status. An 'invaid' status marks the pipeline subscription for later deletion. It is important to not, you must first patch a 'cancelled' status to turn off pipeline subscription jobs. You should never patch a pipeline subscription that is 'active' directly to 'invalid'
storage_group integer Storage group record ID attached to the destination subscription you want to store your data in..
subscription_product_meta_attributes string The id of the account that first created the identity
quantity integer depricated, should always pass '1'
price double depricated, should always pass '0.00'
auto_renew string deprecated, should always pass '1'
date_start string deprecated Current UTC datetime format YYYY-mm-dd HH:mm:ss
date_end string deprecated should always be the same value as into date_start
invalid_subscription string deprecated, should always pass '0'
rabbit_payload_successful string deprecated, should always pass '0'
stripe_subscription_id string deprecated, should always pass ''
remote_identity_id string or null Remote identity connected to the subscription, if none is used, then pass null
unique_hash string Internal Use Only: This is a field our web app checks against a cached value for duplicates. The generation of this hash is complex. Please pass a string containing [] as the value. This represents an empty stringified JSON array.
Subscription Product Meta

The base object for all subscriptions are the same. This makes it easy to templatize. Each product has different "meta" associated with it. In the call to create a subscription you must pass along the correct parameters as part of the subscription_product_meta array. A subscription product meta object within the context of a subscription creation post has a schema that like this:

{
  data_id: 0,
  data_key: 'remote_identity_id',
  data_value: configState.remoteIdentityId,
  data_format: 'STRING',
  product: productId
}
key data type description
data_id integer deprecated: must always pass '0'
data_key string The key part of the key value pair
data_value string The value part of the key value pair
data_format string Used to tell the processor what is in data_value. Accepted values are 'STRING', 'ENCRYPTED_STRING', 'JSON', 'ENCRYPTED_JSON'
product integer The product id, should be the same as the subscription product id.
Headers
name data type description
Content-Type string application/json
Authorization string Openbridge JWT, passed as a authorization bearer type
Parameters

The POST method does not require any parameters.

Responses
http code content-type response
200 application/json Created
Example cURL

This is an example for creating a Selling Partner Orders API subscription.

 {
   "data": {
     "type": "Subscription",
     "attributes": {
       "account": XXXXX,
       "user": YYYYY,
       "product": 53,
       "name": "My unique subscription name",
       "status": "active",
       "quantity": 1,
       "price": 0,
       "auto_renew": 1,
       "date_start": "2023-02-01 00:00:01",
       "date_end": "2023-02-01 00:00:01",
       "invalid_subscription": 0,
       "rabbit_payload_successful": 0,
       "stripe_subscription_id": "",
       "storage_group": ZZZZ,
       "remote_identity": AAAA,
       "unique_hash": "[\"XXXXXXXXXXXXXXXXXXXXXXX\"]",
       "subscription_product_meta_attributes": [
         {
           "data_key": "remote_identity_id",
           "data_value": "AAAA",
           "data_id": 0,
           "data_format": "STRING",
           "product": 53,
         }
       ]
     }
   }
 }

It only requires one subscription_product_meta object and that is the remote_identity_id. You may ask, why is it being passed as both an spm and in the main body of the subscription. This is due to legacy constraints of the processing system, and some requirements of another internal system.

 curl -H "Content-Type: application/json" -H "authorization: Bearer YOURJWTXXXXXXXXXXXX"  -X POST -d '{ "data": { "type": "Subscription", "attributes": { "account": XXXXX, "user": YYYYY, "product": 53, "name": "My unique subscription name", "status": "active", "quantity": 1, "price": 0, "auto_renew": 1, "date_start": "2023-02-01 00:00:01", "date_end": "2023-02-01 00:00:01", "invalid_subscription": 0, "rabbit_payload_successful": 0, "stripe_subscription_id": "", "storage_group": ZZZZ, "remote_identity": AAAA, "unique_hash": "[\"20230201000000\"]", "subscription_product_meta_attributes": [ { "data_key": "remote_identity_id", "data_value": "AAAA", "data_id": 0, "product": 53 }]}}}' https://subscriptions.api.openbridge.io/sub
Example Response

The response will contain many deprecated fields, and will not include the subscription_product_meta array. There will be a list of deprecated fields after the example

{
  "data": {
    "type": "Subscription",
    "id": "XXXXX",
    "attributes": {
      "price": 0.0,
      "status": "active",
      "date_start": "2023-01-31T11:54:45",
      "date_end": "2023-01-31T11:54:45",
      "auto_renew": 1,
      "created_at": "2023-01-31T11:54:48.889618",
      "modified_at": "2023-01-31T11:54:48.889633",
      "quantity": 1,
      "stripe_subscription_id": "",
      "name": "Openbridge Orders ",
      "rabbit_payload_successful": 0,
      "primary_job_id": null,
      "pipeline": null,
      "invalid_subscription": 0,
      "invalidated_at": null,
      "notified_at": null,
      "canonical_name": null,
      "account_id": XXX,
      "product_id": 53,
      "product_plan_id": null,
      "remote_identity_id": AAA,
      "storage_group_id": ZZZ,
      "user_id": YYY,
      "history_requested": 0,
      "unique_hash": "[\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"]"
    },
    "relationships": {
      "account": {
        "data": {
          "type": "Account",
          "id": "342"
        }
      },
      "product": {
        "data": {
          "type": "Product",
          "id": "2"
        }
      },
      "product_plan": {
        "data": null
      },
      "remote_identity": {
        "data": {
          "type": "RemoteIdentity",
          "id": "364"
        }
      },
      "storage_group": {
        "data": {
          "type": "StorageGroup",
          "id": "245"
        }
      },
      "user": {
        "data": {
          "type": "User",
          "id": "309"
        }
      }
    }
  },
  "included": [
    {
      "type": "StorageGroup",
      "id": "245",
      "attributes": {
        "product_id": 37,
        "name": "asdfasdfads",
        "key_name": "984e7c5f47fea2a0-asdfasdfads"
      }
    }
  ]
}
Attribute Keys
name data type description
price double ``
status string ``
date_start datetime string ``
date_end datetime string ``
auto_renew booelean integer depricated
created_at string Datetime the pipeline was created
modified_at string Datetime the pipeline was last modified
quantity integer deprecated
stripe_subscription_id string ``
name string string
rabbit_payload_successful integer Deprecated
primary_job_id integer Deprecated
pipeline string or null Deprecated
invalid_subscription null Deprecated
invalidated_at null Deprecated
notified_at null Deprecated
canonical_name string Deprecated
account_id integer Account id the pipeline subscription is associated with
product_id integer Product id the pipeline subscription is associated with
product_plan_id integer Deprecated
remote_identity_id integer or null The remote identity id the pipeline subscription is associated with
storage_group_id integer The storage group id where the collected data is stored.
user_id string The user id that the subscription pipeline is associated with
history_requested string Deprecated
unique_hash string A required unique hash of the subscription product meta key value pairs
GET https://subscriptions.api.openbridge.io/sub/{id}
Parameters
name required data type description
id yes string The id of the desired subscription record
Responses
http code content-type response
200 application/json OK
Example cURL

This example holds the state that is needed during the Oauth request for a Facebook identity

 curl -X GET -H "Content-Type: application/json" -H "authorization: Bearer YOURJWTXXXXXXXXXXXX" https://subscriptions.api.openbridge.io/sub/{id}'
Example Response

The response includes the id/token and the timestamps the state was created at. This is the same as the response received from a POST call above. Assuming we requested it's token. The response is that of a state that holds an object used to create a Facebook identity.

Example Response

The response will contain many deprecated fields, and will not include the subscription_product_meta array.

{
  "data": {
    "type": "Subscription",
    "id": "XXXXX",
    "attributes": {
      "price": 0.0,
      "status": "active",
      "date_start": "2023-01-31T11:54:45",
      "date_end": "2023-01-31T11:54:45",
      "auto_renew": 1,
      "created_at": "2023-01-31T11:54:48.889618",
      "modified_at": "2023-01-31T11:54:48.889633",
      "quantity": 1,
      "stripe_subscription_id": "",
      "name": "Openbridge Orders ",
      "rabbit_payload_successful": 0,
      "primary_job_id": null,
      "pipeline": null,
      "invalid_subscription": 0,
      "invalidated_at": null,
      "notified_at": null,
      "canonical_name": null,
      "account_id": "XXX",
      "product_id": 53,
      "product_plan_id": null,
      "remote_identity_id": "AAA",
      "storage_group_id": "ZZZ",
      "user_id": "YYY",
      "history_requested": 0,
      "unique_hash": "[\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"]"
    },
    "relationships": {
      "account": {
        "data": {
          "type": "Account",
          "id": "342"
        }
      },
      "product": {
        "data": {
          "type": "Product",
          "id": "2"
        }
      },
      "product_plan": {
        "data": null
      },
      "remote_identity": {
        "data": {
          "type": "RemoteIdentity",
          "id": "364"
        }
      },
      "storage_group": {
        "data": {
          "type": "StorageGroup",
          "id": "245"
        }
      },
      "user": {
        "data": {
          "type": "User",
          "id": "309"
        }
      }
    }
  },
  "included": [
    {
      "type": "StorageGroup",
      "id": "245",
      "attributes": {
        "product_id": 37,
        "name": "asdfasdfads",
        "key_name": "984e7c5f47fea2a0-asdfasdfads"
      }
    }
  ]
}
PATCH https://subscriptions.api.openbridge.io/sub/{id}

The PATCH method is used to update the pipeline subscription record. The schema is similar to that of a POST however it must now include the id, and it is limited on the fields that can be updated.

Patchable Fields
name data type description
name string The name of the pipeline subscription record
status string The status of the pipeline subscription record

The rules for these fields are the same as in the POST method.

Example Payload
{
  "data": {
    "type": "Subscription",
    "id": "XXXXX",
    "attributes": {
      "status": "active"
    }
 }
Headers
name data type description
Authorization string Openbridge JWT, passed as a authorization bearer type
Content-Type string application/json
Parameter
name required data type description
id yes string The id of the pipeline subscription record
Response
http code content-type response
200 application/json OK
Example cURL

This example holds the subscription patch object to update the status to cancelled

 curl -H "Content-Type: application/json" -H "authorization: Bearer eyJh..."  -X PATCH -d '{"data": { "type": "Subscription", "id": "XXXXXXXX", "attributes": { "status": "cancelled" }}}' https://subscriptions.api.openbridge.io/sub/XXXXXXXX
Example Response

The response is the same as in the POST method, with the patched field updated to the new value.

{
  "data": {
    "type": "Subscription",
    "id": "XXXXX",
    "attributes": {
      "price": 0.0,
      "status": "cancelled",
      "date_start": "2023-01-31T11:54:45",
      "date_end": "2023-01-31T11:54:45",
      "auto_renew": 1,
      "created_at": "2023-01-31T11:54:48.889618",
      "modified_at": "2023-01-31T11:54:48.889633",
      "quantity": 1,
      "stripe_subscription_id": "",
      "name": "Openbridge Orders ",
      "rabbit_payload_successful": 0,
      "primary_job_id": null,
      "pipeline": null,
      "invalid_subscription": 0,
      "invalidated_at": null,
      "notified_at": null,
      "canonical_name": null,
      "account_id": XXX,
      "product_id": 53,
      "product_plan_id": null,
      "remote_identity_id": AAA,
      "storage_group_id": ZZZ,
      "user_id": YYY,
      "history_requested": 0,
      "unique_hash": "[\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"]"
    },
    "relationships": {
      "account": {
        "data": {
          "type": "Account",
          "id": "342"
        }
      },
      "product": {
        "data": {
          "type": "Product",
          "id": "2"
        }
      },
      "product_plan": {
        "data": null
      },
      "remote_identity": {
        "data": {
          "type": "RemoteIdentity",
          "id": "364"
        }
      },
      "storage_group": {
        "data": {
          "type": "StorageGroup",
          "id": "245"
        }
      },
      "user": {
        "data": {
          "type": "User",
          "id": "309"
        }
      }
    }
  },
  "included": [
    {
      "type": "StorageGroup",
      "id": "245",
      "attributes": {
        "product_id": 37,
        "name": "asdfasdfads",
        "key_name": "984e7c5f47fea2a0-asdfasdfads"
      }
    }
  ]
}

Selling Partner Product IDs.


Openbridge's Selling Partner products all use the same payload, the difference is product ID sent in the subscription object, and in the subscription_product_meta array objects,

id product name
53 Orders API
55 Finance Real-Time
56 Inbound Fulfillment
57 Settlement Reports
58 Fulfillment
59 Inventory Real-Time
60 Inventory
61 Sales Reports
62 Fees
64 Sales & Traffic
65 Seller Brand Analytics Reports

State API.

The Openbridge State API is a RESTFUL API, that supports. GET andPOST It is used pass the state of a transaction around to other APIs and applications with an identifying token. It is a prerequisite to creating Oauth based identities with the Openbridge OauthAPI.

POST https://state.api.openbridge.io/state/oauth

The payload schema for creating a state token. The type is always ClientState. The object that is passed in the state is the data you want stored in the state represented as a JSON object.

Payload Schema.
{
 data: {
   type: string;
   attributes: {
     state: object
   }
 }
}
Headers
name data type description
Content-Type string application/json
Parameters

The POST method does not require any parameters.

Responses
http code content-type response
201 application/json Created
Example cURL

This example holds the state that is needed during the Oauth request for a Facebook identity

 curl -H "Content-Type: application/json" -X POST -d '{ "data": { "type": "ClientState", "attributes": { "state": { "account_id": "XXX", "user_id": "YYY", "remote_identity_type_id": 2, "region": "global", "return_url": "https://app.openbridge.com/wizards/facebook-page-insights", "shop_url": null }}}}' https://state.api.openbridge.io/state/oauth

Note: The example payload contains information required by the Openbridge Oauth API to start and manage a Facebook Authorization, but it is not restricted to only those key/value pairs. You could for example include your own key/value pair to help with maintaining the state of your application through the identity process.

Example Response

The response includes the id/token and the timestamps the state was created at.

{
  "data": {
    "type": "ClientState",
    "id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "attributes": {
      "token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
      "created_at": "2023-01-26T11:01:03.918717",
      "modified_at": "2023-01-26T11:01:03.918793",
      "state": {
        "account_id": "XXX",
        "user_id": "XXX",
        "remote_identity_type_id": 2,
        "region": "global",
        "return_url": "https://app.openbridge.com/wizards/facebook-page-insights",
        "shop_url": null
      }
    }
  }
}

Note: From the response the id and Token will always be the same.

GET https://state.api.openbridge.io/state/{id/token}
Parameters
name required data type description
id/token yes string The id/token of the desired state record
Responses
http code content-type response
200 application/json OK
Example cURL

This example holds the state that is needed during the Oauth request for a Facebook identity

 curl -X GET https://state.api.openbridge.io/state/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'

Example Response

The response includes the id/token and the timestamps the state was created at. This is the same as the response received from a POST call above. Assuming we requested it's token. The response is that of a state that holds an object used to create a Facebook identity.

{
  "data": {
    "type": "ClientState",
    "id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "attributes": {
      "token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
      "created_at": "2023-01-26T11:01:03.918717",
      "modified_at": "2023-01-26T11:01:03.918793",
      "state": { }
        "account_id": "XXX",
        "user_id": "XXX",
        "remote_identity_type_id": 2,
        "region": "global",
        "return_url": "https://app.openbridge.com/wizards/facebook-page-insights",
        "shop_url": null
      }
    }
  }

Best Practices

Identity Health

Identities are the glue keeping your pipeline subscriptions running. If an authorization attached to an identity is revoked it will cause all pipeline subscriptions attached to it to fail. To get a better understanding of the concept of identities please read Understnading Identities.

Since identiies are so important; Openbridge has a daemon that is set to check identities attached to active subscriptions every 24 hours and send notifications to the affected customers. As an API user we would send notifications to your primary account manager. This allows you to reauthorize the identities that lost authorization so that Openbridge can continue to process data for the affected pipelines.

Retrieving a list of valid or invalid identities

The remote identities API allows you to filter for identities that are valid or invalid. Filters are querystring paramters that are attached to a get call. In this case we want to filter on the invalid_identity. It is a boolean and can be used as invalid_identity=1 to get only invalid identities or invalid_identity=0 to get all valid identities.

When requesting a list of identities you should be using the 'shared remote identities' GET endpoing.

https://remote-identity.api.openbridge.io/sri?invalid_identity=1

Failures on your customer's identities


This is an important feature if you are reselling Openbridge services to your own customers. Since Openbridge has no connection to your customer when our system detects a failed identity we have no way to communicate this failure to them. As a reseller you should have a system in place that maps an identity with the customer in your app who authorized the identity. Periodically you should be querying for invalid identities, and when one is detected you should be communicating the failure with your customers so that they can reauthorized the identity.

Frequently Asked Questions

How do I determine if an Amazon Seller has a unified or multi-market account?

GET /sp/marketplaces

To determine if a Seller has a unified account, you can call the API with the remote identity in question. If you get a list of more than one market returned, it is almost certainly a unified/multi-market account. In this case, rather than setting up a subscription for each country, you just needed one for that identity. We are still making a request for each country, but doing so under the unified account.

Here is an example request:

GET https://service.api.openbridge.io/service/sp/marketplaces/<remote-identity-id>
Authorization: Bearer XXXXX

In the response, you can see the list of associated markets:

{
 "data": [
 {
  "id": "X",
  "countryCode": "FR",
  "name": "Amazon.fr",
  "defaultCurrencyCode": "EUR",
  "defaultLanguageCode": "fr_FR",
  "domainName": "www.amazon.fr"
 },
 {
  "id": "X",
  "countryCode": "NL",
  "name": "Amazon.nl",
  "defaultCurrencyCode": "EUR",
  "defaultLanguageCode": "nl_NL",
  "domainName": "www.amazon.nl"
 },
 {
  "id": "X",
  "countryCode": "PL",
  "name": "Amazon.pl",
  "defaultCurrencyCode": "PLN",
  "defaultLanguageCode": "pl_PL",
  "domainName": "www.amazon.pl"
 },
 {
  "id": "X",
  "countryCode": "GB",
  "name": "Amazon.co.uk",
  "defaultCurrencyCode": "GBP",
  "defaultLanguageCode": "en_GB",
  "domainName": "www.amazon.co.uk"
 },
 {
  "id": "X",
  "countryCode": "DE",
  "name": "Amazon.de",
  "defaultCurrencyCode": "EUR",
  "defaultLanguageCode": "de_DE",
  "domainName": "www.amazon.de"
 },
 {
  "id": "X",
  "countryCode": "ES",
  "name": "Amazon.es",
  "defaultCurrencyCode": "EUR",
  "defaultLanguageCode": "es_ES",
  "domainName": "www.amazon.es"
 },
 {
  "id": "X",
  "countryCode": "FR",
  "name": "Non-Amazon",
  "defaultCurrencyCode": "EUR",
  "defaultLanguageCode": "fr_FR",
  "domainName": "si-prod-fr-marketplace.stores.amazon.fr"
 },
 {
  "id": "X",
  "countryCode": "SE",
  "name": "Amazon.se",
  "defaultCurrencyCode": "SEK",
  "defaultLanguageCode": "sv_SE",
  "domainName": "www.amazon.se"
 },
 {
  "id": "X",
  "countryCode": "TR",
  "name": "Amazon.com.tr",
  "defaultCurrencyCode": "TRY",
  "defaultLanguageCode": "tr_TR",
  "domainName": "www.amazon.com.tr"
 },
 {
  "id": "X",
  "countryCode": "DE",
  "name": "Non-Amazon",
  "defaultCurrencyCode": "EUR",
  "defaultLanguageCode": "de_DE",
  "domainName": "si-prod-marketplace-de.stores.amazon.de"
 },
 {
  "id": "X",
  "countryCode": "IT",
  "name": "SI Prod IT Marketplace",
  "defaultCurrencyCode": "EUR",
  "defaultLanguageCode": "it_IT",
  "domainName": "siprod.stores.amazon.it"
 },
 {
  "id": "X",
  "countryCode": "ES",
  "name": "SI Prod ES Marketplace",
  "defaultCurrencyCode": "EUR",
  "defaultLanguageCode": "es_ES",
  "domainName": "siprod.stores.amazon.es"
 },
 {
  "id": "X",
  "countryCode": "BE",
  "name": "Amazon.com.be",
  "defaultCurrencyCode": "EUR",
  "defaultLanguageCode": "fr_BE",
  "domainName": "www.amazon.com.be"
 },
 {
  "id": "X",
  "countryCode": "IT",
  "name": "Amazon.it",
  "defaultCurrencyCode": "EUR",
  "defaultLanguageCode": "it_IT",
  "domainName": "www.amazon.it"
 },
 {
  "id": "X",
  "countryCode": "GB",
  "name": "SI UK Prod Marketplace",
  "defaultCurrencyCode": "GBP",
  "defaultLanguageCode": "en_GB",
  "domainName": "siprodukmarketplace.stores.amazon.co.uk"
 }
 ]
}

How do I get profile information associated with a remote identity.

Openbridge does not store profile tied to remote identities. Instead during the creation process we query third-party APIs through our service API based on a product. If you need to know what remote identity is tied to a third-party profile. The remote identity id can be found in the subscription pipeline record tied to that third-party profile.

API Error Handling Guide

Proper error handling is essential for ensuring smooth interactions and resolving issues promptly. Please look at the following guidelines when handling errors in your application.

Error Response Structure

Our APIs follow a RESTful standardized error response structure, utilizing HTTP status codes in the header to indicate the nature of the error. Error responses are returned in JSON format containing a list of errors encountered before the process's termination. Typically, the JSON will include a stack trace which usually contains the problem's source, to which you can figure out how to debug the problem or contact Openbridge Support to help debug the issue.

Common Error Scenarios

Authentication Errors

  • Bad Request (400): Invalid input parameters or request payload.
  • Unauthorized (401): Invalid or missing authentication credentials.
  • Forbidden (403): Insufficient permissions to access the requested resource.
  • Validation Errors
  • Not Found (404): This means that the resource you are looking for either never existed or may have been deleted, As in a deleted subscription or identity.
  • Too Many Requests (429 or 503): Exceeded API rate limits. Implement exponential backoff for retries.
  • Internal Server Error (500) is a generic error thrown when something uncaught or unexpected fails. For example, a load balancer not routing requests correctly could result in a 500 error. If you see this error consistently please contact support@openbridge.com

Handling Client Errors

If you are creating an application or have a website that delivers services to your customers when encountering errors, ensure proper validation of input parameters and provide meaningful feedback to your users. Log error details for debugging purposes without exposing sensitive information.

Handling Server Errors

Implement retry mechanisms with exponential backoff to handle transient server errors gracefully. Report persistent server errors to our support team for investigation at support@openbridge.com.

Request Limits and Governance for Openbridge Embedded API

Overview

When using the Openbridge embedded API, it is essential to understand that most requests are governed by the rate limits and policies of the upstream data sources and systems. This document outlines the impact of these limits on data retrieval speeds and provides context for the constraints you may encounter.

Example: Amazon Seller and Vendor Reporting API Rate Limits

The speed at which data can be retrieved from Amazon is primarily dictated by the limits imposed by the Amazon Seller and Vendor Reporting API. This API has a strict rate limit of 0.0167 requests per second, which equates to approximately 60 requests per hour. These limits are shared across all applications or developers associated with a particular seller or vendor account, including Openbridge.

Key Points:
  • Rate Limit: 0.0167 requests per second (60 requests per hour)
  • Shared Across Applications: All requests from any application or developer for a specific seller or vendor account count against this limit.
  • Impact on Data Retrieval: The low limit can significantly affect the time required to retrieve large volumes of data, especially in regions like the EU where this issue is particularly critical.

Example Scenario: Data Retrieval for Seller ACME CORP

To illustrate the impact of these limits, consider a hypothetical seller, ACME CORP, set up on 4/23, with multiple report types requested for a 364-day history:

  • Report Types Requested:

  • sp_ba_market_basket

  • sp_ba_repeat_purchase

  • sp_ba_search_terms_by_day

  • sp_ba_search_terms_by_month

  • sp_ba_search_terms_by_quarter

  • sp_ba_search_terms_by_week

  • Total Reports:

  • 2200 reports requested under the subscription 1111111.

  • Additional requests under subscriptions 22222, 33333, 444444, 55555, and 66666, leading to a total of 2994 historical requests (jobs).

  • Approximately 18,000 specific reports requested from the API for a 12-month period.

Calculating Time for Data Retrieval

Given the API's rate limits, the time to complete all requests can be substantial:

  • Minimum Requests:

  • 18,000 requests / 60 requests per hour = 300 hours (approximately 13 days)

  • Maximum Requests:

  • 56,000 requests / 60 requests per hour = 933 hours (approximately 39 days)

These calculations assume that the application uses 100% of the API's capacity, excluding other applications. The shared rate limit of 60 requests per hour can significantly extend the time required to complete large data retrieval tasks. Always plan your data retrieval strategies with these constraints in mind to manage expectations and optimize performance. See the section on retry and backoff for strategies to deal with upstream API limits.

For further assistance or inquiries about optimizing your data retrieval process, please contact our support team at support@openbridge.com.

Best Practices

Follow these best practices for robust error handling: Thoroughly test error scenarios during API integration. Log error details without exposing sensitive information. Implement retry mechanisms with exponential backoff for transient errors. Provide meaningful error messages for client-side validation errors.

Example Code

Below is a reference that what is means to have an implementation that handles different types of errors including authentication errors, validation errors, and internal server errors we detailed above. This implementation includes detailed error handling and logging to manage these scenarios effectively. while the example uses Python, we strongly advise a similar conceptual approach in whatever language you are employing. This is an example, and not code meant to be copied and pasted and used as it is a generic reference.

import time
import random
import requests

def retry_with_exponential_backoff(max_retries=5, initial_delay=1, backoff_factor=2, max_delay=60):
 def decorator(func):
  def wrapper(*args, **kwargs):
   retries = 0
   delay = initial_delay
   while retries < max_retries:
    try:
     response = func(*args, **kwargs)
     if response.status_code in (429, 503): # Too Many Requests or Service Unavailable
      raise Exception("Rate limit exceeded or service unavailable")
     return response
    except requests.exceptions.HTTPError as http_err:
     status_code = http_err.response.status_code
     if status_code in (401, 403):
      print(f"Authentication error ({status_code}): {http_err.response.text}")
      raise
     elif status_code == 400:
      print(f"Validation error (400): {http_err.response.text}")
      raise
     elif status_code in (429, 503):
      retries += 1
      if retries >= max_retries:
       raise
      print(f"Rate limit error ({status_code}). Retrying in {delay:.2f} seconds...")
      time.sleep(delay)
      delay = min(delay * backoff_factor, max_delay) * (1 + random.uniform(-0.1, 0.1)) # adding jitter
     elif status_code == 500:
      retries += 1
      if retries >= max_retries:
       raise
      print(f"Internal server error (500). Retrying in {delay:.2f} seconds...")
      time.sleep(delay)
      delay = min(delay * backoff_factor, max_delay) * (1 + random.uniform(-0.1, 0.1)) # adding jitter
     else:
      print(f"HTTP error ({status_code}): {http_err.response.text}")
      raise
    except Exception as e:
     retries += 1
     if retries >= max_retries:
      raise
     print(f"Error: {e}. Retrying in {delay:.2f} seconds...")
     time.sleep(delay)
     delay = min(delay * backoff_factor, max_delay) * (1 + random.uniform(-0.1, 0.1)) # adding jitter
  return wrapper
 return decorator

@retry_with_exponential_backoff()
def example_api_call():
 # Replace this with your actual API call
 print("Attempting API call...")
 response = requests.get("https://api.example.com/endpoint") # Simulated API endpoint
 response.raise_for_status() # Raise an error for bad responses
 return response

# Test the retry mechanism
try:
 response = example_api_call()
 print("API call successful:", response.status_code)
except Exception as e:
 print(f"Final failure after retries: {e}")

The example call shows that when an exception occurs, it checks the status code and handles it accordingly:

  • 401 Unauthorized and 403 Forbidden: Print an authentication error message and raise the exception.
  • 400 Bad Request: Print a validation error message and raise the exception.
  • 404 Not Found: This means that the resource you are looking for either never existed or may have been deleted, As in a deleted subscription or identity.
  • 429 Too Many Requests and 503 Service Unavailable: Implement exponential backoff and retry.
  • 500 Internal Server Error: Implement exponential backoff and retry.
  • Other HTTP Errors: Print the error message and raise the exception.

Support Resources

If you need any more help, please contact our support team at support@openbridge.com.

Changelog

See the current CHANGELOG for updates, fixes, and enhancements.

Docs

For more examples on configuration, guides, and constraints please refer to the docs: Openbridge Documentation

If you have not used Openbridge before, you can get a 30-day free trial @ the Openbridge Website. For other guides, tips, or how-to examples, visit us @ the Openbridge Blog

Issues

If you have any problems with or questions about the API, please contact us through a GitHub issue or via the official support portal.

Contributing

You are invited to contribute new features, fixes, or updates, large or small; we are always thrilled to receive requests, and do our best to process them as fast as we can.

Before you start to code, we recommend discussing your plans through a GitHub issue, especially for more ambitious endeavors. This gives other contributors a chance to point you in the right direction, give you feedback on your approach, and help you find out if someone else is working on the same thing.

References

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages