Partner Integration

Updated on October 2, 2024

Automatically Provision and Manage Releva Accounts in 5 Easy Steps #

This page is indeded for Releva partners. If you are an e-commerce owner and would like to integrate Releva into your shop, please take a look at the Standard Integration instead.

Step 1: Provision Cryptographic Keys #

In order to communicate with Releva securely, we need to exchange some secrets. Please follow the procesdure below to generate a key pair.

ssh-keygen -t rsa -b 4096 -m PEM -f jwtRS256.key
# Don't add passphrase
openssl rsa -in jwtRS256.key -pubout -outform PEM -out jwtRS256.key.pub

This process will produce 2 files – jwtRS256.key (your private key) and jwtRS256.key.pub (your public key). Please keep your private key secret, and send only your public key to support [at] releva ai so we can register it into the system. In exchange, we will send you a partner token, which you must include as part of every request to Releva partner APIs.

Step 2: Provision Releva Account for Client #

Whenever a client wises to use Releva, you can provision a Releva account using the following API call:

curl -H 'Content-Type: application/json' -H 'x-rlv-partner-token: <yourPartnerToken>' -XPOST https://releva.ai/api/v0/partners/domains -d'{
  "payload": "....." // a string, signed with your private key. The payload must be encoded according to the JWT standard.
}'
#example in Node.js:
return jwt.sign(data, process.env.PRIVATE_KEY, {
      algorithm: 'RS512',
      expiresIn: '1h',
    });


# object to sign
{
  "url": "my-shop.com",
  "name": "My Shop",
  "currencyCode": "USD",
  "contactEmail": "hello@releva.ai",
  "timezoneOffset": "+0300",
  "locale": "en",
  "platform": "custom"
}
FieldTypeDescription
urlStringThe URL of the shop without the protocol. For example, for https://my-shop.com, the value of this field should be my-shop.com.
nameStringThe name of the shop you would like to register.
currencyCodeISO-4217 StringThe primary currency of the shop, in ISO-4217 format.
contactEmailISO-8601 Timezone Offset StringThe email address of the primary contact for this shop.
timezoneOffsetStringThe timezone offset of the shop specified in ISO-8601 format. For example, for a shop in UTC, the offset can be either Z or +0000. For UTC + 2 hours, the offset should be +0200. For UTC- 2 hours, the offset should be -0200.
localeISO-639-1 StringThe primary locale of the shop, in ISO-639-1 format. For example, for a shop whose primary language is English, the value here would be en. For German, it would be de.
platformStringThe platform of the shop. It should be one of magento1, magento2, opencart, woocommerce, custom.If the platform is not directly supported by Releva, put custom here.

A successfully executed request will return a status code 201 if the shop was created within the request, or a status code 200 if the shop already existed prior to the request.

The JSON response will have the following structure:

{
  "domain": {
    "accessToken": "...",
    "secretKey": "....",
    ...
    "pages": [
      {"token": "...", "name": "....", ....},
      ....
    ]
  }
}

It is important to save the acessToken, secerKey, and the list of pages as page name -> token so that you can use them to perform the Standard Integration of the shop that was just provisioned.

Step 2: Obtain Releva Subscription Information #

You may skip this step unless you will be handling billing and invoicing for the client.

In case you will be handling billing and invoicing for the client, you need to know about what subscriptions are available so that you can present them to the client.

In order to obtain up-to-date subscription options and pricing information for Releva, please call the following API:

curl -XPOST -H 'content-type: application-json' -H 'x-rlv-partner-token: <yourPartnerToken>' /api/v0/partners/subscriptions -d'{
  "payload": "....." // a string representing the JSON below signed with your private key
}'

# object to sign
{
  "shop": "my-shop.com",
}

A successfully executed request will return a status code 200 and the following response:

[
        {
          name: 'AI Hub',
          summary: 'The ChatGPT Alternative For Creative Marketing.',
          description:
            'Create, Document, Collaborate and Share, Brand Consistent, Persuasive and Audience Tailored Content.',
          allowedActions: ['createContent', 'generatedContentList', 'brandContext', 'imagesList'],
          subscriptionTieredPricings: [],
          subscriptionDynamicPricings: [
            {
              unit: 'seats',
              unitPrice: 19.99,
            },
          ],
          type: 'modular',
        },
          {
          name: 'Mail & Push',
          summary: 'Target, Engage, Convert: Mail & Push Delivers.',
          description:
            'Design, Execute, and Optimize personalized, consistent, and compelling emails, banners, pop-ups and push notifications that resonate directly with your target audience.',
          allowedActions: [
            'emailsList',
            'emailsCreate',
            'emailsUpdate',
            'emailsDelete',
            'pushNotificationsList',
            ...
          ],
          subscriptionTieredPricings: [
            {
              name: 'Standard',
              treshold: 0,
              price: 15.99,
              unit: 'subscribers',
            },
          ],
          subscriptionDynamicPricings: [
            {
              unitPrice: 0.012,
              unit: 'subscribers',
            },
          ],
          type: 'modular',
        },
      ...
]

Step 3: Assign Subscriptions to Shop #

You may skip this step unless you will be handling billing and invoicing for the client.

After you present the subscription details to the shop owner, and they chose which subscriptions they would like to sign up for, you can make the following call to Releva to assign the chosen subscriptions to the shop:

curl -XPOST -H 'content-type: application-json' -H 'x-rlv-partner-token: <yourPartnerToken>' https://releva.ai/api/v0/partners/domains/subscriptions/confirm -d'{
  "payload": "....." // a string representing the JSON below signed with your private key
}'

# object to sign
{
  "shop": "my-shop.com",
   "start": "2022-10-22T00:00:00.000Z",
   "end": "2022-11-22T00:00:00.000Z",
   "subscriptionIds": [id1, id2, ...],
   "dynamicPriceCapUSD" : 123.45
   "fixedPriceAmountUSD" : 234.56
}
FieldTypeDescription
shopStringThe URL of the shop without the protocol. For example, for https://my-shop.com, the value of this field should be my-shop.com.
trialDaysIntegerThe trial days to grant to the shop. Value may be obtained in the previous step but may be different depending on what you have agreed with the client.
startISO-8601 StringThe start date of the first billing period.
endISO-8601 StringThe end date of the first billing period.
“subscriptionIds”Array[Integer]The ids of the subscriptions the shop owner would like to sign up for
“dynamicPriceCapUSD”Float (Optional)The maximum amount that can be charged for the combined usage pricing of all subscriptions within a single billing period.
“frixedPriceCapUSD”Float (Optional)The maximum amount that can be charged for the combined tiered pricing of all subscriptions within a single billing period.

A successful request will return status 200 and the following response:

{
  "subscriptions": [...],
  "billingPeriod": {
   "start": "2022-10-22T00:00:00.000Z",
   "end": "2022-11-22T00:00:00.000Z",
   "trialDays": 14,
   ...
  },
}

Step 4: Single Sign-on (SSO) into the Releva Admin Panel #

To allow client stakeloders to log into https://releva.ai/admin and make adjustments to the Releva configuration, you can generate single-sign on links as follows:

https://releva.ai/api/admin/users/partnerSignin/<yourPartnerToken>/<payload>

Where payload is a string representing the JSON below signed with your private key:

{
  "shop": "my-shop.com",
  "user": {
    "firstName": "John",
    "lastName": "Smith",
    "email": "john@smith.com",
  }
}

Vising the Single sign-on link will have the following effect:
1. If the user does not yet exist in Releva, it will be created

2. If the user does not have access to this shop, access will be granted

3. If the user was just created, a welcome email will be sent with a link to confirm the Releva user account and set the password.

4.The user will be signed in and reditected to https://releva.ai/admin.

Please note that SSO links have a limited validity so they should be generated on-the-fly and not cached!

Step 5: Implement Account Management Webhooks #

You may skip this step unless you will be handling billing and invoicing for the client.

There are 3 webhooks that you should implement to be able to fully manage account subscriptions and invoice clients:

5.1 Usage Record Create Webhook #

You may skip this step unless you will be handling billing and invoicing for the client.


Implementing this webhook allows you to receive and store Releva usage records for shop you have provisioned within Releva. Releva will make the following request to your endpoint:

curl -H 'content-type: application/json' -H 'authorization: Bearer <shopSecretKey>' -XPOST https://your-partner-service-url.com/releva/webhooks/usageRecords -d'{
"usageRecords": [
    {
      "day": "2022-10-10",
      "type": "monthlyActiveUsers/subscribers/pageViews/whatsappMessages/textMessages/seats/viberTextMessages/viberMultimediaMessages",
      "unitPrice": "19.99",
      "amount": "3",
      "billableAmount": "2",
      "totalPrice": "39.98",
      "reference": "description of the subscription and the pricing component that this record refers to",
      "preaggregated": true/false
    },
    ...
  ]
}'

You can then identify the shop that these usage records are meant for by looking up based on the secret key received in the authorization header.

Then, you can use the information in the usage records for a given billing period to invoice the customer.

Note that there are two types of usage records – preaggregated, and non-preaggregated. When invoicing, you should have a single line item for each unique refernce within the billing period.

For references which have preaggregated: true, you should take the latest record within the billing period.

For references which have preaggregated: false, you should take the sum of amounts and unitPrices for all records within the billing period that fall outside the trial period.

5.2 Subscriptions Change Request Webhook #

Implementing this webhook allows Releva to prompt a client to change their subscription selection when they have reached the limit of their subscription or they request access to more advanced features. Releva will make the following request to your endpoint:

curl -H 'content-type: application/json' -H 'authorization: Bearer <shopSecretKey>' -XPOST https://your-partner-service-url.com/releva/subscriptions

{
  "subscriptionIds": [id1, id2, id2]
}

You should return a confirmationUrl where the user can confirm their selection and agree to the updated pricing.


{
  "confirmationUrl": "https://your-partner-portal.com/releva/subscriptions/confirm/token/..."
}

That’s all, folks!

Appendix: Toggling Shop Integrations #

If you wish to pause a shop integration, you may do so using the request below. Pausing the integration will stop both the frontend and backend integrations, and will therefore stop the accumulation of usage charges.

curl -XPUT -H 'content-type: application-json' -H 'x-rlv-partner-token: <yourPartnerToken>' https://releva.ai/api/v0/partners/domains -d'{
  "payload": "....." // a string representing the JSON below signed with your private key
}'

# object to sign
{
  "shop": "my-shop.com",
  "running":false
}

To resume a shop integration, use the same request as the one above but change the “running” field to true.