Skip to main content

Braintree

Braintree is PayPal's payment gateway: transactions, refunds, disputes, customers, payment methods and recurring billing. The connector pins your gateway to https://payments.braintree-api.com and seals your API key there, so an agent can read your payment data and act on it without ever holding the credential. Because Braintree's current API is a single GraphQL endpoint, this connector works differently to the REST connectors in the catalog — read Per-operation scoping is not possible yet before you use it in production.

What you need

A Braintree API key pair: a public key and a private key.

  1. Sign in to the Braintree Control Panel (or the sandbox Control Panel to try it out first).
  2. Select the gear icon in the top right, then API, and scroll to API Keys.
  3. Generate a new API key, or select View on an existing one to reveal its private key.
  4. Copy the Public Key and the Private Key.

Braintree authenticates the GraphQL API with HTTP Basic, using the public key as the username and the private key as the password. Permaura expects the pair in exactly that form, so paste the credential as:

your_public_key:your_private_key

Least privilege here means a dedicated user, not a narrower key. A Braintree API key inherits whatever its owning user can do, and there is no per-key scope selector. Under the gear icon → Team → New User, create a user for the agent, tick API access, and give it a role whose rights cover only what you want reachable — a role with read rights alone if this is for reporting. Generate the key pair as that user. Removing the user revokes the key.

Add the connection

In the console, open Access → Connections → Add connection, pick Braintree from the catalog, and paste the public:private pair when prompted. The credential 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 connection's one capability arrives switched off. Turn it on deliberately, then create a grant before any agent can use it.

What the agent can do

ActionWhat it doesOn by default
graphql.executeSends one GraphQL document (query, variables, operationName) to POST /graphqlNo — approval-gated

That is the whole list, and the reason is below.

Per-operation scoping is not possible yet

Every Braintree operation — transactions, refundTransaction, chargePaymentMethod, createCustomer — is the same HTTP call: POST /graphql with the operation in the request body. Permaura scopes REST connectors by pinning a method and a path per capability, and there is nothing to pin here. A capability called refunds.create would be a fiction: it would accept any document the agent sent, including a charge.

So the connector declares one honest capability, graphql.execute, marked critical and approval-required. Every call stops and waits for a human on your paired device, who sees the document before it runs. That approval gate is what stands in for per-operation scoping.

Permaura's GraphQL importer, which will parse a schema and turn named operations into individually scoped capabilities, is not built yet. Until it lands, the honest recommendation is to leave this connection approval-gated. If you want an agent to move money through Braintree unattended, do it behind a small REST service of your own and connect that instead.

Good to know

  • Sandbox is a different host. This connector is pinned to production, https://payments.braintree-api.com. A pinned base URL is the SSRF guard, so one connection can never reach both hosts — and there is nowhere in Add connection to override it, because POST /v1/connections/from-preset takes a name and a label and nothing else. To reach your sandbox merchant, install a second copy of the manifest under its own id: take braintree.json, change "id" to something like braintree-sandbox, change base_url to https://payments.sandbox.braintree-api.com, POST it to /v1/connectors/install, and create the connection from that. The two then sit side by side in the catalog with separate credentials.
  • The API version is pinned to Braintree-Version: 2026-01-01 in the manifest. Braintree requires a YYYY-MM-DD version header on every request and suggests using the date you began integrating; fixing it in the manifest means an upstream schema change cannot silently alter what your agent gets back. Braintree publishes a schema changelog if you want to see what a newer date would add.
  • GraphQL errors come back as HTTP 200. Braintree returns 200 OK with an errors array in the body for authentication failures, validation problems and declined transactions alike. Do not treat a 200 as success — an agent (or you, reading the audit log) has to check the body.
  • Redaction is weaker here than on a REST connector. The gateway blanks values by matching response field names, and bin, last4, expirationMonth, expirationYear, cardholderName, email, phoneNumber, streetAddress, postalCode and clientToken are all on the list. But in GraphQL the caller chooses the response keys: a query written as { x: last4 } comes back under x, a name the filter has never heard of. So it catches an ordinary query and cannot be relied on against a deliberate one. Treat it as tidying, not as a boundary — the approval gate is the control that actually holds.
  • Rate limits are unpublished. PayPal does not document a threshold for Braintree; it throttles traffic that looks abusive and lifts the limit once the pattern stops. Do not let an agent poll in a loop, and page search results with first and after rather than asking for everything at once.
  • Your merchant id is not part of the credential. Braintree's server SDKs take merchant id, public key and private key together. The GraphQL API authenticates on the key pair alone, so paste only public:private — a merchant id in that field will fail the Basic auth check.
  • 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.