NAV
shell

Introduction

Quaderno is a SaaS app and set of APIs to automate and improve tax management in businesses of all sizes. Here are some resources that will help you understand the basics of all of them.

The documentation is organized into these major areas:

Not a developer?

A custom Quaderno integration requires you to either have basic coding skills or hire a developer. But we made Quaderno really easy to connect with many third-party platforms without coding experience at all. Check our documentation on one-click integrations, such as for Shopify, Amazon FBA, and WooCommerce.

Need more help?

Just send us an email. Please include your code or the API request and response when possible. We’re always happy to help out with code or any other questions you might have.

Quaderno Sandbox

Quaderno Sandbox is a safe space to experiment with our set of APIs and products, testing new features or fine-tunning your Quaderno workflows and integrations, without the worries of breaking things while learning.

Quaderno Sandbox has feature parity with the real live environment plus all the new features, testable in advance but without the fuss of dealing with real user data! It's perfect for connecting your payment's processor testing accounts, knowing all will behave just as fine on the live production servers.

Quaderno Sandbox is a separate environment, with it's own URL https://sandbox-quadernoapp.com and credentials. This means your credentials for the Production environment won't work on Quaderno Sandbox. You'll need to create a new Quaderno Sandbox account.

Purge your Quaderno Sandbox documents with:

curl --user sk_your-secret-key:x \
     --request POST \
     --url http://your-url.sandbox-quadernoapp.com/api/purge

Quaderno.js

Quaderno.js is a handy small javascript library to calculate taxes directly from your frontend. It fits great with our own checkout experience, Quaderno Checkout, as well as with your own forms, to calculate taxes in real time.

To unleash all the power of our server-side APIs like Tax calculations and Tax ID validations, Billing and Tax reporting and tracking, go check our API.

Including Quaderno.js

  <script src="https://js.quaderno.io/v4/"></script>

However you’re using Quaderno.js, you always begin by including the library and setting your public API key*.

To get started, include this script on your pages — it should always be loaded directly from https://js.quaderno.io

While the private API key is meant for being used server-side, secured in your backend, the public API key is only used by Quaderno.js, and only allow access to our tax calculations engine. No data can be leaked from your account with the public API key.

Supported browsers

Quaderno.js strives to support all recent versions of major browsers. For the sake of security and providing the best experience to the majority of customers, we do not support browsers that are no longer receiving security updates and represent a small minority of traffic.

If you have an issue with Quaderno.js on a specific browser, please contact us so we can improve its support.

Quaderno.js methods

When you include the Quaderno.js script in your page, a global Quaderno object will be available with the following methods:

init( publishableKey )

  // never expose your private API key on your frontend, use the public API key instead
  Quaderno.init(publishableKey).then(function(){
    console.log('Success');
  }).catch(function(error){
    console.log(error.description, error.messages);
  });

Async request. Use this method to initialize the global object Quaderno.

This method returns a Promise which resolves if the publishableKey verification was successful. If there's any issue, this method returns a Promise which rejects with an error object. This object has either:

bindForm( formId )

  // to use along with the deferred automatic init
  Quaderno.bindForm("#formId").then(function(){
    console.log('Success');
  }).catch(function(error){
    console.log(error.description, error.messages);
  });

Async request. This method also initializes the global object Quaderno from a form object.

This method returns a Promise which resolves if the publishableKey verification was successful. If there's any issue, this method returns a Promise which rejects with an error object. This object has either:

calculateTaxes( options )

  // use `options` along with Custom init
  var options = { taxClass: 'eservice', postalCode: '123456', city: 'Dublin', country: 'IE' }

  Quaderno.calculateTaxes(options).then(function(taxObject){
    console.log(taxObject.name, taxObject.rate, taxObject.country); // ie. "VAT", 23, "IE"
  })

Async request. Calculates the taxes based on the billing data from options object

Available options are documented below:

Attribute Mandatory Description
taxClass No Indicates the tax class of the transaction.
postalCode No ZIP or postal code.
city No The customer's city. Used to make more accurate calculations based on the postal code
country No ISO 3166-1 alpha-2
businessNumber No A valid business number. Quaderno validates EU VAT numbers, ABN, and NZBN.
  <!-- no need to fill the `options` of calculateTaxes() with automatic inits -->
  <form id="quaderno-payment-form" data-publishable-key="pk_xxxxxxxx">
    <select data-quaderno="country"></select>
    <input data-quaderno="postalCode" />
    ...
  </form>

This method returns a Promise which resolves with a tax object.

Note that when you calculate taxes using our Tax Rates API, parameters follow a slighty different naming scheme:

Quaderno.js Tax Rates API
taxClass tax_code
businessNumber tax_id
taxType tax_behavior

calculatePrice([options])

  options = { amount: 100, quantity: 2 }
  priceObject = Quaderno.calculatePrice(options);

  priceObject.subtotal;
  priceObject.taxes;

Helper method which calculates the final price of the product, tax inclusive.

Available options are documented below:

Attribute Mandatory Description
amount No Amount you are going to charge your customer, in cents.
quantity No Quantity of the products.
taxType No If the tax is included or excluded

The options can be omitted if you've set a form using bindForm with its proper data-quaderno attributes, or if you've retrieved the product information from Quaderno with getProduct

This method returns a price object with the following attributes:

destroy()

  Quaderno.destroy();

Remove event listeners from the DOM elements. It might be useful if you have single-page apps and have tied the Quaderno object to a form via bindForm or the simple initialization.

getProduct( productId )

  Quaderno.getProduct("productId").then(function(product){
    console.log(product.name, product.unitCost, product.code);
  });

Async request. Retrieve the product info identified by productId. Returns a product object in the resolve function.

You can register your products manually in quadernoapp.com/products or programatically with our API.

getCoupon( couponCode )

  Quaderno.getCoupon("couponCode").then(function(product){
    console.log(coupon.amountOff);
  });

Async request. Retrieve the product info identified by couponCode. Returns a coupon object in the resolve function.

You can register your products manually in quadernoapp.com/checkout/coupons or programatically with our API.

getLastTax()

  taxes = Quaderno.getLastTax();

  taxes.name;
  taxes.rate;
  taxes.country;

Reads the last calculated tax and returns a tax object.

validateBusinessNumber(businessNumber, country)

  Quaderno.validateBusinessNumber("GB1234567", "GB").then(function(response){
    console.log(response.valid);
  }).catch(function(error){
    console.log(error.descriptions);
  });

Async request. This method validates the customer's business number. Currently Quaderno validates EU VAT numbers, ABN, and NZBN.

Please keep in mind that business numbers are not actually validated when using Quaderno Sandbox.

This method returns a result object with the following attribute:

Quaderno.js objects

This section documents the objects you'll receive from Quaderno.js.

The Tax object

This object is passed by the resolve function of the Promise returned by the Quaderno.calculateTaxes method or by invoking Quaderno.getLastTax.

Attribute Description
country A valid ISO 3166-1 alpha-2 code.
region State/Region/Province.
county County (only for US sales tax).
city City (only for US sales tax)
countyTaxCode County tax code (if applicable on US sales taxes)
cityTaxCode City tax code (if applicable on US sales taxes)
name Name of the tax.
rate Tax rate in percentage (6.5).
extraName Name of the extra tax.
extraRate Tax rate in percentage of the extra tax.
taxClass The tax class of the transaction. Can be one of the following: standard, eservice, ebook or saas.
businessNumberValid This attribute is only present if you've set a businessNumber during the calculation request. It can be true, null or false.

The Product object

This object contains the relevant information related to the productID you've set. It's returned by the resolve function of Quaderno.getProduct.

Attribute Description
code The product code in Quaderno.
name The name of the product.
image URL to the image of the product.
unitCost Unit price of the product.
currency A valid ISO-4271 code.
kind Indicates if the product is either a subscription or a one-off sale.
taxClass The tax class for the product. Can be one of the following: standard, eservice, ebook or saas.
taxType Indicates if the tax is included or excluded from the product price.

The Coupon object

This object contains the relevant information related to the couponCode you've set. It's returned by the resolve function of Quaderno.getCoupon.

Attribute Description
code The product code in Quaderno.
kind Indicates if the coupon is percent_off or amount_off
amountOff The amount off.
currency The currency of the amount off.
percentOff The percent off.
redeemable Indicates if the coupon is redeemable

Initializing Quaderno.js

For your convenience, there are a few different ways to initialize Quaderno.js.

You can avoid this behavior using the custom init method.

Simple automatic init

    <head>
      <script src="https://js.quaderno.io/v4/"></script>
    </head>

    <body>
      <form id="quaderno-payment-form" data-publishable-key="pk_xxxxxxxx">
        <select data-quaderno="country"></select>
        <input data-quaderno="postalCode" />
        ...
      </form>
    </body>

Automatically loads quaderno.js if the form has the quaderno-payment-form id and a valid data-publishable-key. Optionally you can also set a data-product-id.

The input fields will be automatically detected as long as they have the data-quaderno with their definition:

Deferred automatic init

    <head>
      <script src="https://js.quaderno.io/v4/"></script>
    </head>

    <body>
      <form id="payment-form" data-publishable-key="pk_xxxxxxxx" data-product-id="prod_xxxxxxxx">
        <select data-quaderno="country"></select>
        <input data-quaderno="postalCode" />
        <!-- … -->
      </form>

      <script>
        Quaderno.bindForm('#payment-form').then(function(response) {
          console.log(response.product);
        }).catch(function(error){
          console.log(error.description, error.messages);
        });
      </script>
    </body>

If you don't want the form to load automatically, you can load it later by not using the "quaderno-payment-form" id, and then call the bindForm method whenever you want.

Custom init

    <label for="country">
      <span>Country</span>
      <input id="country" name="country" value="ES" />
    </label>

    <label for="postal-code">
      <span>Postal code</span>
      <input id="postal-code" name="postal-code" value="35007" />
    </label>

    <script>
      Quaderno.init(publishableKey).then(function() {
        console.log('Quaderno.js successfully initialized');
      }).catch(function(error) {
        console.log(error.description, error.messages);
      });
    </script>

Futhermore, you can also dissociate Quaderno from the DOM by setting the Quaderno object properties by yourself.

This means you need to explicitly set your publishableKey as argument for the init call, instead of using the data-publishable-key html attribute in your form.

Afterwards, you'll need to specify all options for calculateTaxes().

Calculating taxes from your frontend with Quaderno.js

In this example, we are going to handle UI updates on the relevant fields to force tax calculations and show it in a <span>. We'll be validating Tax IDs (business numbers) too when given one. We'll use the custom init method in this example.

<form>
  <label for="country">
    Country
    <select id="country">
      <option value="US" selected>United States</option>
      <option value="GB">United Kingdom</option>
      <option value="DE">Germany</option>
      <option value="FR">France</option>
      <option value="IT">Italy</option>
      <option value="ES">Spain</option>
      <option value="CA">Canada</option>
      <option value="AU">Australia</option>
    </select>
  </label>

  <label for="postal-code">
    Postal code
    <input id="postal-code">
  </label>

  <label for="business-number">
    Business number:
    <input id="business-number">
  </label>

    <label for="tax-class">
    Tax Code:
    <select id="tax-class">
      <option value="standard">standard</option>
      <option value="eservice">eservice</option>
      <option value="ebook">ebook</option>
      <option value="saas">saas</option>
    </select>
  </label>

</form>
  Taxes: <span id="tax-rate"></span>

  <script>

    // never expose your private API key on your frontend, use the public API key instead
    let publishableKey = "pk_test_xxxxxxxxxxxxxxxxxxxx";
    // we're not attaching Quaderno.js to our form, so we need to use init:
    Quaderno.init(publishableKey).then(function(){
      console.log('Quaderno.js successfully initialized');
    }).catch(function(error){
      console.log(error.description, error.messages);
    });

    // this is a custom function to be called each time the user introduces new data
    function reloadTaxes(options){
      console.log("Calling calculateTaxes with params", options)
      Quaderno.calculateTaxes(options).then(function(taxObject){
        // Remember, you need to be registered on the tax jurisdiction to get the tax rate
        console.log("Taxes calculated:", taxObject)
        document.querySelector('#tax-rate').innerHTML = taxObject.name + " " + taxObject.rate + "%"; // ie.: VAT 20%
      })
    }

    // Handle change events on the relevant user-inputs so that the Tax Rate it's automatically updated
    document.querySelector('#country').addEventListener('change', function () {
      country = this.value
      postalCode = document.querySelector('#postal-code').value
      businessNumber = document.querySelector('#business-number').value

      reloadTaxes({ country: country, postalCode: postalCode, businessNumber: businessNumber})
    })

    document.querySelector('#postal-code').addEventListener('change', function () {
      postalCode = this.value
      country = document.querySelector('#country').value
      businessNumber = document.querySelector('#business-number').value

      reloadTaxes({ country: country, postalCode: postalCode, businessNumber: businessNumber })
    })

    document.querySelector('#business-number').addEventListener('change', function () {
      businessNumber = this.value
      country = document.querySelector('#country').value
      postalCode = document.querySelector('#postal-code').value

      // We're also validating Tax ID (business number) when given one
      Quaderno.validateBusinessNumber(businessNumber, country).then(function(){
        reloadTaxes({ businessNumber: businessNumber, country: country, postalCode: postalCode })
      })
    })

    document.querySelector('#tax-class').addEventListener('change', function () {
      taxClass = this.value
      country = document.querySelector('#country').value
      postalCode = document.querySelector('#postal-code').value
      businessNumber = document.querySelector('#business-number').value

      reloadTaxes({ taxClass: taxClass, country: country, postalCode: postalCode, businessNumber: businessNumber })
    })
  </script>

The more common use of Quaderno.js is to calculate taxes by invoking the method Quaderno.calculateTaxes.

In the example on the right, we're showing a form with different countries and tax codes (called taxClass in Quaderno.js). Instead of using the super-simple approach of binding to your form by specifying a quaderno-payment-form id and a valid data-publishable-key, we're first initializing Quaderno.js with our public API key using the custom init method, and then collecting the data that will form our options for calculateTaxes(options) manually, with document.querySelector('#value-id'), anytime these receive a change event from the DOM.

The result from calculateTaxes(options) is then painted on the UI. We're also validating the Tax ID (business number) with validateBusinessNumber when given one.

On this example, when selecting "United States" and introducing "7501" as postal code, the console prints:

Calling calculateTaxes with params:
{
    "country": "US",
    "postalCode": "7501",
    "businessNumber": ""
}

Taxes calculated:
{
  country: "US"
  extraName: null
  extraRate: null
  name: "Sales tax"
  rate: 6.25
  region: "TX"
}

Note that we're not calling the performant getLastTax() method because in this case the data changes everytime. If you already got your tax rate and need that data again later in your checkout process, you may want to call calculateTaxes(options) once and after that rely on getLastTax().

Remember that Quaderno.js will only return tax rates for those tax jurisdictions where you are registered. Follow the links to learn more on tax jurisdictions and setting up tax jurisdictions.

You can check the code to the right live in this Codepen:

Checkout

Quaderno Checkout is a checkout form that you can use to sell your digital products and subscriptions from any website, email or message.

A Checkout Session represents your customer’s session as they pay for one-off purchases or subscriptions through Checkout.

You can create simple sessions by using Checkout Links.

But if you want to fine tune the Checkout experience for a particular customer or create sessions on-the-fly, you can also create a Checkout Session directly. You can find more information about how to manage the Sessions in our API docs

How to create a Checkout Session and fulfill the order

In this example, you will learn how to create a Checkout Session for your customer and how to asynchrnonously identify the transaction once it has been completed by using the checkout.succeeded event.

Part 1: Creating the Session:

First you need to dynamically create a Checkout Session for your customer (more details here)

curl -u sk_test123123123123123:x \
     -H 'Content-Type: application/json' \
     -X POST \
     -d '{"billing_details_collection":"auto","cancel_url":"string","coupon_collection":true,"customer":{"first_name":"John","last_name":"Doe","email":"john@doe.com"},"items":[{"product":"prod_61ffa845b4a0b8"}]}' \
     'https://demo-account.quadernoapp.com/api/checkout/sessions.json'

This will return a new session like the following:

{
      "id":1,
      "status":"completed",
      "billing_details_collection":"required",
      "cancel_url":"http://go.back.com",
      "coupon_collection":true,
      "locale":"auto",
      "payment_methods":["card", "paypal"],
      "success_url":"http://success.com?prod=1",
      "custom":{},
      "items":[
         {
            "product":"prod_61ffa845b4a0b8",
            "amount":999.0,
            "name":"A test item",
            "description":"This a test item.",
            "currency":"EUR",
            "quantity":1
         }
      ],
      "customer":{
         "billing_city":null,
         "billing_country":null,
         "billing_postal_code":null,
         "billing_street_line_1":null,
         "billing_street_line_2":null,
         "company":"",
         "email":"john@doe.com",
         "first_name":"John",
         "last_name":"Doe",
         "tax_id":null,
         "business_number":null
      },
      "permalink":"https://demo-account.quadernoapp.com/checkout/session/8ccf3fdc42b85800188b113b81d3e4212ef094b3"
   }

The session's permalink (e.g https://demo-account.quadernoapp.com/checkout/session/xxxxx) is the URL your customer will use to complete their purchase.

Part 2: Fulfilling the order

Due to the SCA (Strong Customer Authentication) requirements, the only way to guarantee the transaction has succeeded is by checking it asynchrnously via webhooks.

Once your customer visits the permalink and completes the purchase, you need to set up some webhooks to track succeeded sessions.

Quaderno provides a checkout.succeeded event to send you a notification every time a customer completes a purchase on the Checkout.

You can subscribe to Quaderno webhooks by using our API (more details here):

# body
'{
    "url": "http://yourapp.com/notifications",
    "events_types": ["checkout.succeed"]
}'

curl -u YOUR_API_KEY:x \
     -H 'Content-Type: application/json' \
     -X POST \
     --data-binary @body.json \
     'https://ACCOUNT_NAME.quadernoapp.com/api/webhooks.json'

or by using the web interface (in Developers -> Webhooks -> Create Webhook):

checkout.succeeded

Once you've subscribed to the checkout.succeeded event you need to create an endpoint in your app to handle the webhooks notifications.

This is a what a checkout.succeeded notification should look like:

{
   "event_type":"checkout.succeeded",
   "data":{
      "object":{
         "message":{
            "response_message":"Checkout succeeded",
            "status_code":200
         },
         "transaction_details":{
            "session":43,
            "session_permalink":"https://demo.quadernoapp.com/checkout/session/8ccf3fdc42b85800188b113b81d3e4212ef094b3",
            "gateway":"stripe",
            "type":"charge",
            "description":"Unicorn",
            "customer":"cus_FXesSyaK3CG8Oz",
            "email":"john@doe.com",
            "transaction":"pi_1F2ZYtEjVHvINKlcq2as8H5V",
            "product_id":"prod_61ffa845b4a0b8",
            "tax_name":"VAT",
            "tax_rate":20.0,
            "extra_tax_name":null,
            "extra_tax_rate":null,
            "iat":1564647784,
            "amount_cents":1500,
            "amount":"15.00",
            "currency":"EUR"
         },
         "contact":{
            "id":547540,
            "kind":"company",
            "first_name":"John ",
            "last_name":"Doe",
            "full_name":"John  Doe",
            "contact_name":null,
            "street_line_1":"Fake Street 1",
            "postal_code":"SW15 5PU",
            "city":null,
            "region":null,
            "country":"GB",
            "email":"john@doe.com",
            "web":null,
            "language":"EN",
            "tax_id":null,
            "vat_number":null
         }
      }
   }
}

With the session id, product_id and the customer's email you should be able to identify the customer and fulfill the order.

Apps

With the Quaderno API, it’s easy to build a partner integration to add tax management and billing features to your product.

For example, if you are a marketplace, you can integrate sales tax calculation using the Quaderno API so your users can calculate taxes automatically in their checkout forms depending on their customers' locations.

But it’s not just marketplaces that work great with Quaderno - we’ve seen partner integrations built with all kinds of software from tools to manage sport clubs to WordPress blogs.

Integrating with Quaderno has the power to add huge value for your users, streamlining their businesses processes and providing a great experience.

Every partner integration is different, so this document can’t tell you exactly what to do, but we’ll explain the flows you should handle, and give you some ideas of how to provide the best experience for your users.

Connecting your users' accounts

To calculate taxes or issue receipts for your users, you’ll need access to their Quaderno account so you can make API requests on their behalf.

Our OAuth flow allows you to securely obtain an access token for a Quaderno account without having to have your user’s password or do any manual setup.

There are four key benefits to getting access to your users’ accounts using OAuth:

The process for your user looks like this:

  1. Your user clicks a button in your UI to start the process of connecting with Quaderno.
  2. You generate a link to the authorization page, embedding details of your app (which we’ll set up next) as well as a scope to specify the level of access you want your user to give you.
  3. You redirect your user to the generated link. Your user lands on our site, where they create a Quaderno account or log in to their existing one, and agree to grant your app access.
  4. We redirect your user’s browser back to you with a code query parameter.
  5. You exchange the code for a permanent access token, which you store so that you can use it to make API requests on your user’s behalf.

Creating an app

Before we can get started, you need to create an "app" which represents your partner integration in the Quaderno system. You’ll be issued with a client ID and secret, which you’ll use to identify yourself when sending users to the OAuth flow and swapping codes for access tokens.

First sign up for a Quaderno account in our sandbox testing environment and then create an app.

You’ll need to provide a name and the URL of your website (where users can go to read more about your product or your integration with Quaderno).

Once your user has completed the OAuth flow, they will be redirected to your application using the redirect_url parameter you provide. For security reasons, this can’t be just any internet URL, so you will also need to configure one callback URL here (which must exactly match the parameter).

Once you’ve created an app, you’ll see it in the list of your apps. Click on your newly-created app, and take a note of the Client ID and Client Secret.

First, you need to install an Oauth client library. For example, in Ruby you can use the oauth2 gem:

echo "gem 'oauth2'" >> Gemfile
bundle install

Once we’ve installed the library, we can build a link to the authorization page. We’ll have to pass in a number of parameters, including the client_id and client_secret, as well as a few parameters that will vary by library. These can include:

Option Required  Description
redirect_uri Yes The URL to send your users to once they've agreed to connect their account to Quaderno (as well if they deny authorisation or something goes wrong, in which case we'll pass you details of the error). This must exactly match one of the callback URLs you specified above.
scope No The level of access you want to your users' Quaderno accounts - this may either be read_write or read_only. Default is read_only.
state No Any value you pass in here will be included as a querystring parameter when we redirect back to your redirect URL. Please note that this value can be tampered with by your user, and so shouldn't be trusted implicitly. We recommend using this parameter for a CSRF token.
require 'oauth2'

# You should store your client ID and secret in environment variables rather than
# committing them with your code
oauth = OAuth2::Client.new(ENV['QUADERNO_CLIENT_ID'],
                           ENV['QUADERNO_CLIENT_SECRET'],
                           site: 'https://sandbox-quadernoapp.com',
                           authorize_url: '/oauth/authorize',
                           token_url: '/oauth/token')

authorize_url = oauth.auth_code.authorize_url(redirect_uri: 'https://yourapp.com/redirect', 
                                              scope: 'read_only')

redirect_to authorize_url

Run this code to generate a link to the OAuth flow. Head over to the link you’ve just generated in an Incognito window, and you’ll see our OAuth flow.

Getting an access token

On the signup form, we recommend creating a second sandbox account using a different email address. This will replicate what your users will experience when connecting to your partner integration, and will give you an example account which you can use from the perspective of one of your users.

Once your user has either signed up or logged in, and then approved your app’s access to their account, they’ll be sent to your app’s redirect URI with a temporary code which you’ll see in the query parameters, as well as any state you provided.

You should use the OAuth client library we set up earlier to fetch an access token using the code. This is a permanent access token which allows you to use the API on behalf of your merchant at any time.

require 'oauth2'

oauth = OAuth2::Client.new(ENV['QUADERNO_CLIENT_ID'],
                           ENV['QUADERNO_CLIENT_SECRET'],
                           site: 'https://sandbox-quadernoapp.com',
                           authorize_url: '/oauth/authorize',
                           token_url: '/oauth/token')

response = oauth.auth_code.get_token(
  params[:code], # use exactly the same access token as you did in the last step
  redirect_uri: 'https://yourapp.com/redirect'
)

# You should store the user's access token - you'll need it to make API requests on their
# behalf in future. If you want to handle webhooks for your users, you should also store
# their account ID which will allow you to identify webhooks belonging to them.
current_user.update!(quaderno_access_token: response.token,
                     quaderno_account_id: response['account_id'])

Whether you are developing a mobile, web, or desktop application, it is important not to pass the client secret to your user’s device as it could be used to impersonate your app. The process of exchanging a code for an access token should be done on your server so your client secret can be kept private.

You’ll want to store this access token in your database for use in the future to make requests to the Quaderno API on your user’s behalf. Make sure you keep it safe and secure, as it gives full access to your user’s account.

Revoking access

To disconnect an account from your platform, POST your client_id, your client_token, and the user's access token to /oauth/revoke

  HTTParty.post('https:/sandbox-quadernoapp.com/oauth/revoke', body: {
      client_id: ENV['QUADERNO_CLIENT_ID'],
      client_secret: ENV['QUADERNO_CLIENT_SECRET'],
      token: USER_TOKEN
    })