Skip to main content

Square

The Square connector reaches the Square Connect API v2 for one Square account. It is good for the reporting side of a seller's day: which payments came in at which location, what an order contained, who the customer was, and what is in the catalog. It can also take a payment and refund one, but both actions ship switched off and approval-gated, because both move real money.

What you need

A Square access token. You have two ways to get one, and they behave differently.

The simple path: a personal access token. Sign in to the Square Developer Console, open your application, and select Credentials in the left pane. Each application carries two tokens: a sandbox access token and a production access token. Copy the one for the environment you mean to use.

A personal access token is unscoped

Square's personal access tokens grant full access to every resource in the Square account that owns them. There is no permission selector, so you cannot narrow one down the way you can a Stripe restricted key. What limits an agent here is Permaura, not Square: the connector exposes ten pinned endpoints and nothing else, the two money-moving ones arrive disabled, and a grant decides which agent sees which. Enable only the actions you actually want reachable.

The scoped path: OAuth. If you want a genuinely narrow token, register an OAuth application instead. In the Developer Console, open your application's OAuth page and set the Redirect URL — Square requires HTTPS, so use https://<your-gateway-host>/oauth/callback for a tunnelled gateway. HTTP is accepted only against localhost in the Square Sandbox, in which case use http://localhost:7376/oauth/callback. Then request the least privilege you need. The connector's manifest advertises the read set:

MERCHANT_PROFILE_READ, PAYMENTS_READ, ORDERS_READ, CUSTOMERS_READ, ITEMS_READ

Add PAYMENTS_WRITE only if you intend to switch on Take a payment or Refund a payment. Those five scopes cover everything that is on by default.

The OAuth path needs gateway 1.1.0 or later

From 1.1.0 the gateway runs the authorisation code flow itself. You send your Square application's client id, secret and redirect URL to POST /v1/connections/:id/oauth/start on the gateway, open the link it returns, approve, and the gateway exchanges the code, seals the tokens, and refreshes them from then on. There is no "Sign in with Square" button in the console yet, so this runs through the gateway's REST API today. The redirect_uri you send must match the Redirect URL registered in the Developer Console character for character, the link is single-use and expires after ten minutes, PKCE is added automatically because the manifest records that Square supports it, and if you have a device enrolled for approvals, run the start call from the gateway's own host rather than over a tunnel.

Square OAuth access tokens expire after 30 days, which used to mean rotating the credential by hand. Square issues a refresh token alongside them and the gateway now uses it, so an OAuth connection keeps working unattended. A personal access token does not expire at all, which is why it is still the simpler starting point.

Add the connection

In the console, go to Access → Connections → Add connection, pick Square from the catalog, and paste the access token once. It is sealed on your gateway and never displayed again. Nothing can use it until a grant allows it.

What the agent can do

ActionWhat it doesOn by default
locations.listLists the seller's locationsYes
payments.listLists payments, filtered by date range or locationYes
payments.readReads one paymentYes
orders.searchSearches orders across up to ten locationsYes
orders.readReads one orderYes
customers.listLists customersYes
customers.readReads one customerYes
catalog.listLists catalog objects, filtered by typeYes
payments.createTakes a payment from a source idNo, and needs approval
refunds.createRefunds a payment, in full or in partNo, and needs approval

orders.search is a POST, but it only reads: Square has no GET /v2/orders, so listing orders means posting a query. The manifest marks it as a search so it stays on by default. The two writes below it are the genuine ones, and neither can be undone by an agent — a refund returns money to a customer, and a payment takes it.

Good to know

  • The sandbox is a different host, and it needs its own connector. This connector is pinned to production, https://connect.squareup.com/v2. That base URL is the SSRF guard, and it comes from the manifest rather than the connection: Add connection has no base URL field, and POST /v1/connections/from-preset takes only a name and a label. So pointing an agent at Square Sandbox means installing your own copy of the manifest, with the host swapped, under a different id:

    # take scripts/connectors/square.json, change "id" to "square-sandbox", set
    # "base_url" to "https://connect.squareupsandbox.com/v2", and repoint the oauth
    # block at https://connect.squareupsandbox.com/oauth2/authorize and /token
    curl -X POST http://127.0.0.1:7376/v1/connectors/install \
    -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' \
    -d "{\"version\": 1, \"manifest\": $(cat square-sandbox.json)}"

    It appears in the catalog as a user-provenance entry (no Verified connector badge, because you authored it), and you paste the sandbox access token into a connection made from that. A production token against the sandbox host fails to authenticate, and one connection can never reach both environments.

  • The API version is pinned to Square-Version: 2026-07-15 in the manifest. Square dates its API versions and otherwise falls back to whatever version your application is pinned to in the Developer Console, which can be changed out from under you. Fixing it here means an upstream change cannot silently alter what your agent gets back.

  • Writes need an idempotency_key. Both payments.create and refunds.create require a unique string of up to 45 characters, and Square uses it to collapse retries. An agent that reuses one gets the original result back rather than a second charge, which is what you want; an agent that sends a fresh one on every retry can double-charge.

  • orders.search needs location_ids. Square does not have a global order list. Pass the location ids you care about — up to ten, all belonging to the same merchant — which usually means calling locations.list first.

  • Narrow catalog.list with types. Left unspecified it returns every top-level object type. Pass something like ITEM,ITEM_VARIATION,CATEGORY to keep responses manageable, and follow the cursor for more.

  • Card and contact details are redacted. last_4, exp_month, exp_year, cardholder_name, billing_address, shipping_address, email_address, phone_number and buyer_email_address are stripped from responses before the agent sees them. The agent can tell you a payment of £42 completed at your Soho location without learning whose card it was.

  • Rate limits are unpublished. Square does not document a threshold and different endpoints throttle differently; you find out by getting a 429 with a RATE_LIMITED error. Do not let an agent poll in a loop, and page results with cursor rather than asking for everything at once.

  • 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.