Skip to main content

Paddle

Paddle is a merchant of record: it sells your product on your behalf and handles sales tax, payment processing and compliance. The connector pins your gateway to https://api.paddle.com and seals your API key there, so an agent can answer questions about your revenue — who is subscribed, what a customer has been billed, which transactions failed — without holding a credential that could bill or refund anyone. The three capabilities that do move money are approval-gated and start switched off.

What you need

A Paddle API key.

  1. Sign in to Paddle and go to Developer Tools → Authentication.
  2. Select the API keys tab, then New API key.
  3. Name it something you will recognise later, such as permaura.
  4. Choose the permissions. For read-only use, tick product.read, price.read, customer.read, subscription.read and transaction.read. Add transaction.write, adjustment.write and subscription.write only if you intend to enable the three write capabilities below.
  5. Set an expiry (Paddle defaults to 90 days, maximum one year) and save. Copy the key straight away — it starts pdl_live_apikey_ and Paddle shows it only once. Lose it and you have to revoke and reissue.

Paddle's write permissions imply the matching read permission, so a key with transaction.write can also read transactions. Grant the narrowest set that covers what you plan to switch on.

Add the connection

In the console, open Access → Connections → Add connection, pick Paddle from the catalog, and paste the API key when prompted. It is sealed on your gateway at that moment and is never displayed again — you can rotate or replace it, but not read it back.

The nine read capabilities arrive switched on; the three writes arrive switched off. Nothing is usable until a grant allows it.

What the agent can do

ActionWhat it doesOn by default
products.listLists products, filterable by status and typeYes
products.readRetrieves one product by idYes
prices.listLists prices, filterable by id, product_id, status and recurringYes
customers.listLists customers, filterable by email, search and statusYes
customers.readRetrieves one customer by idYes
subscriptions.listLists subscriptions, filterable by customer_id, price_id and statusYes
subscriptions.readRetrieves one subscription by idYes
transactions.listLists transactions, filterable by customer_id, subscription_id, status and billed_atYes
transactions.readRetrieves one transaction by idYes
transactions.createCreates a billable transaction against a customerNo — approval-gated
adjustments.createRefunds or credits a transactionNo — approval-gated
subscriptions.cancelCancels a subscriptionNo — approval-gated

The three writes are marked critical and require a human approval on your paired device for every call, even after you switch them on. That is deliberate: each one either bills a customer, gives money back, or ends a paying relationship.

transactions.create does not capture a payment on the spot, but it is not harmless either. With collection_mode of manual and status of billed, Paddle sends your customer a real invoice with payment terms. With collection_mode of automatic it returns a checkout.url for them to pay through, and once that payment completes Paddle creates a subscription for any recurring items on the transaction. Read items, customer_id, collection_mode and status before you approve one.

adjustments.create covers both refunds and credits — the action field in the request body chooses between refund and credit, and Paddle requires a transaction_id and a reason with either.

subscriptions.cancel takes an effective_from of next_billing_period (the default, which schedules the cancellation for the end of the current period) or immediately. Check which one the request is asking for before you approve it; they are very different outcomes for the customer.

Good to know

  • Sandbox is a different host. This connector is pinned to production, https://api.paddle.com. Paddle's sandbox lives at https://sandbox-api.paddle.com with its own separate API keys. A pinned base URL is the SSRF guard — an agent can never reach any other host through this connection — and POST /v1/connections/from-preset gives you no way to override it. To test against sandbox, install a second copy of the manifest under its own id: take paddle.json, change "id" to something like paddle-sandbox, change base_url to https://sandbox-api.paddle.com, POST it to /v1/connectors/install, and create the connection from that.
  • The API version is pinned to Paddle-Version: 1. Paddle treats the header as optional and falls back to your account's default version, but pinning it means a change to your account default cannot silently alter what your agent gets back. Version 1 is the only version Paddle has published.
  • A refund is submitted, not done. Paddle itself reviews most refunds on live accounts, so a successful adjustments.create with action: refund comes back as pending_approval and later becomes approved or rejected. Watch the adjustment.updated webhook rather than assuming the money has moved. Credits need no Paddle review and are created as approved. On sandbox, refunds are auto-approved every ten minutes.
  • Customer data is redacted. email, first_line, second_line, city, postal_code, cardholder_name, last4, expiry_month, expiry_year and customer_ip_address are stripped from responses before the agent sees them. An agent can tell you a customer's subscription is past due; it cannot read their address or card details.
  • There is no prices.read. Fetching prices by id is covered by prices.list with the id filter, which takes a comma-separated list of price ids — one capability instead of two.
  • Paging uses after, not page numbers. Every list capability accepts per_page (default 50, maximum 200) and after, which takes the id of the last item you saw. Paddle returns the next cursor in meta.pagination.
  • API keys expire. If you set the default 90-day expiry, the connection will start failing on that date. Rotate the key in Paddle and paste the new one into the connection before then, or set a longer expiry when you create it.
  • The kill switch is instant. Disabling the connection in the console refuses every call through it immediately, across every agent and grant, without unpicking individual permissions.