Square
Access the Square API with managed OAuth authentication. Process payments, manage customers, orders, catalog items, inventory, and invoices.
Quick Start
# List locations
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/squareup/v2/locations')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Base URL
https://gateway.maton.ai/squareup/{native-api-path}
Replace {native-api-path} with the actual Square API endpoint path. The gateway proxies requests to connect.squareup.com and automatically injects your OAuth token.
Authentication
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEY
Environment Variable: Set your API key as MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Getting Your API Key
- Sign in or create an account at maton.ai
- Go to maton.ai/settings
- Copy your API key
Connection Management
Manage your Square OAuth connections at https://ctrl.maton.ai.
List Connections
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=squareup&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Create Connection
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'squareup'}).encode()
req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Get Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
json
{
"connection": {
"connection_id": "21fd90f9-5935-43cd-b6c8-bde9d915ca80",
"status": "ACTIVE",
"creation_time": "2025-12-08T07:20:53.488460Z",
"last_updated_time": "2026-01-31T20:03:32.593153Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "squareup",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
Delete Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Specifying Connection
If you have multiple Square connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/squareup/v2/locations')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '21fd90f9-5935-43cd-b6c8-bde9d915ca80')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If omitted, the gateway uses the default (oldest) active connection.
API Reference
Locations
List Locations
GET /squareup/v2/locations
Get Location
GET /squareup/v2/locations/{location_id}
Create Location
POST /squareup/v2/locations
Content-Type: application/json
{
"location": {
"name": "New Location",
"address": {
"address_line_1": "123 Main St",
"locality": "San Francisco",
"administrative_district_level_1": "CA",
"postal_code": "94102",
"country": "US"
}
}
}
Update Location
PUT /squareup/v2/locations/{location_id}
Content-Type: application/json
{
"location": {
"name": "Updated Location Name"
}
}
Merchants
Get Merchant
GET /squareup/v2/merchants/me
List Merchants
GET /squareup/v2/merchants
Payments
List Payments
GET /squareup/v2/payments
With filters:
GET /squareup/v2/payments?location_id={location_id}&begin_time=2026-01-01T00:00:00Z&end_time=2026-02-01T00:00:00Z
Get Payment
GET /squareup/v2/payments/{payment_id}
Create Payment
POST /squareup/v2/payments
Content-Type: application/json
{
"source_id": "cnon:card-nonce-ok",
"idempotency_key": "unique-key-12345",
"amount_money": {
"amount": 1000,
"currency": "USD"
},
"location_id": "{location_id}"
}
Update Payment
PUT /squareup/v2/payments/{payment_id}
Content-Type: application/json
{
"payment": {
"tip_money": {
"amount": 200,
"currency": "USD"
}
},
"idempotency_key": "unique-key-67890"
}
Complete Payment
POST /squareup/v2/payments/{payment_id}/complete
Content-Type: application/json
{}
Cancel Payment
POST /squareup/v2/payments/{payment_id}/cancel
Content-Type: application/json
{}
Refunds
List Refunds
GET /squareup/v2/refunds
Get Refund
GET /squareup/v2/refunds/{refund_id}
Create Refund
POST /squareup/v2/refunds
Content-Type: application/json
{
"idempotency_key": "unique-refund-key",
"payment_id": "{payment_id}",
"amount_money": {
"amount": 500,
"currency": "USD"
},
"reason": "Customer requested refund"
}
Customers
List Customers
GET /squareup/v2/customers
Get Customer
GET /squareup/v2/customers/{customer_id}
Create Customer
POST /squareup/v2/customers
Content-Type: application/json
{
"given_name": "John",
"family_name": "Doe",
"email_address": "[email protected]",
"phone_number": "+15551234567"
}
Update Customer
PUT /squareup/v2/customers/{customer_id}
Content-Type: application/json
{
"email_address": "[email protected]"
}
Delete Customer
DELETE /squareup/v2/customers/{customer_id}
Search Customers
POST /squareup/v2/customers/search
Content-Type: application/json
{
"query": {
"filter": {
"email_address": {
"exact": "[email protected]"
}
}
}
}
Orders
Create Order
POST /squareup/v2/orders
Content-Type: application/json
{
"order": {
"location_id": "{location_id}",
"line_items": [
{
"name": "Item 1",
"quantity": "1",
"base_price_money": {
"amount": 1000,
"currency": "USD"
}
}
]
},
"idempotency_key": "unique-order-key"
}
Get Order
GET /squareup/v2/orders/{order_id}
Update Order
PUT /squareup/v2/orders/{order_id}
Content-Type: application/json
{
"order": {
"location_id": "{location_id}",
"version": 1
},
"fields_to_clear": ["line_items"]
}
Search Orders
POST /squareup/v2/orders/search
Content-Type: application/json
{
"location_ids": ["{location_id}"],
"query": {
"filter": {
"state_filter": {
"states": ["OPEN"]
}
}
}
}
Batch Retrieve Orders
POST /squareup/v2/orders/batch-retrieve
Content-Type: application/json
{
"location_id": "{location_id}",
"order_ids": ["{order_id_1}", "{order_id_2}"]
}
Catalog
List Catalog
GET /squareup/v2/catalog/list
With type filter:
GET /squareup/v2/catalog/list?types=ITEM,CATEGORY
Get Catalog Object
GET /squareup/v2/catalog/object/{object_id}
Upsert Catalog Object
POST /squareup/v2/catalog/object
Content-Type: application/json
{
"idempotency_key": "unique-catalog-key",
"object": {
"type": "ITEM",
"id": "#new-item",
"item_data": {
"name": "Coffee",
"description": "Hot brewed coffee",
"variations": [
{
"type": "ITEM_VARIATION",
"id": "#small-coffee",
"item_variation_data": {
"name": "Small",
"pricing_type": "FIXED_PRICING",
"price_money": {
"amount": 300,
"currency": "USD"
}
}
}
]
}
}
}
Delete Catalog Object
DELETE /squareup/v2/catalog/object/{object_id}
Batch Upsert Catalog Objects
POST /squareup/v2/catalog/batch-upsert
Content-Type: application/json
{
"idempotency_key": "unique-batch-key",
"batches": [
{
"objects": [...]
}
]
}
Search Catalog Objects
POST /squareup/v2/catalog/search
Content-Type: application/json
{
"object_types": ["ITEM"],
"query": {
"text_query": {
"keywords": ["coffee"]
}
}
}
Get Catalog Info
GET /squareup/v2/catalog/info
Inventory
Retrieve Inventory Count
GET /squareup/v2/inventory/{catalog_object_id}
Batch Retrieve Inventory Counts
POST /squareup/v2/inventory/counts/batch-retrieve
Content-Type: application/json
{
"catalog_object_ids": ["{object_id_1}", "{object_id_2}"],
"location_ids": ["{location_id}"]
}
Batch Change Inventory
POST /squareup/v2/inventory/changes/batch-create
Content-Type: application/json
{
"idempotency_key": "unique-inventory-key",
"changes": [
{
"type": "ADJUSTMENT",
"adjustment": {
"catalog_object_id": "{object_id}",
"location_id": "{location_id}",
"quantity": "10",
"from_state": "NONE",
"to_state": "IN_STOCK"
}
}
]
}
Retrieve Inventory Adjustment
GET /squareup/v2/inventory/adjustments/{adjustment_id}
Invoices
List Invoices
GET /squareup/v2/invoices?location_id={location_id}
Get Invoice
GET /squareup/v2/invoices/{invoice_id}
Create Invoice
POST /squareup/v2/invoices
Content-Type: application/json
{
"invoice": {
"location_id": "{location_id}",
"order_id": "{order_id}",
"primary_recipient": {
"customer_id": "{customer_id}"
},
"payment_requests": [
{
"request_type": "BALANCE",
"due_date": "2026-02-15"
}
],
"delivery_method": "EMAIL"
},
"idempotency_key": "unique-invoice-key"
}
Update Invoice
PUT /squareup/v2/invoices/{invoice_id}
Content-Type: application/json
{
"invoice": {
"version": 1,
"payment_requests": [
{
"uid": "{payment_request_uid}",
"due_date": "2026-02-20"
}
]
},
"idempotency_key": "unique-update-key"
}
Publish Invoice
POST /squareup/v2/invoices/{invoice_id}/publish
Content-Type: application/json
{
"version": 1,
"idempotency_key": "unique-publish-key"
}
Cancel Invoice
POST /squareup/v2/invoices/{invoice_id}/cancel
Content-Type: application/json
{
"version": 1
}
Delete Invoice
DELETE /squareup/v2/invoices/{invoice_id}?version=1
Search Invoices
POST /squareup/v2/invoices/search
Content-Type: application/json
{
"query": {
"filter": {
"location_ids": ["{location_id}"],
"customer_ids": ["{customer_id}"]
}
}
}
Pagination
Square uses cursor-based pagination. List endpoints return a cursor field when more results exist:
GET /squareup/v2/payments?cursor={cursor_value}
Response includes pagination info:
{
"payments": [...],
"cursor": "next_page_cursor_value"
}
Continue fetching by passing the cursor value in subsequent requests until no cursor is returned.
Code Examples
JavaScript
const response = await fetch(
'https://gateway.maton.ai/squareup/v2/locations',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const data = await response.json();
Python
import os
import requests
response = requests.get(
'https://gateway.maton.ai/squareup/v2/locations',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
)
data = response.json()
Notes
- All amounts are in the smallest currency unit (e.g., cents for USD: 1000 = $10.00)
- IDs are alphanumeric strings
- Timestamps are in ISO 8601 format (e.g.,
2026-02-07T01:59:28.459Z) - Most write operations require an
idempotency_keyto prevent duplicate operations - Some endpoints require specific OAuth scopes (CUSTOMERS_READ, ORDERS_READ, ITEMS_READ, INVOICES_READ, etc.)
- IMPORTANT: When using curl commands, use
curl -gwhen URLs contain brackets to disable glob parsing - IMPORTANT: When piping curl output to
jqor other commands, environment variables like$MATON_API_KEYmay not expand correctly in some shell environments
Error Handling
| Status | Meaning |
|---|---|
| 400 | Missing Square connection or bad request |
| 401 | Invalid or missing Maton API key |
| 403 | Insufficient OAuth scopes |
| 404 | Resource not found |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from Square API |
Error Response Format
{
"errors": [
{
"category": "INVALID_REQUEST_ERROR",
"code": "NOT_FOUND",
"detail": "Could not find payment with id: {payment_id}"
}
]
}
Troubleshooting: API Key Issues
- Check that the
MATON_API_KEYenvironment variable is set:
echo $MATON_API_KEY
- Verify the API key is valid by listing connections:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Troubleshooting: Invalid App Name
- Ensure your URL path starts with
squareup. For example:
- Correct:
https://gateway.maton.ai/squareup/v2/locations - Incorrect:
https://gateway.maton.ai/v2/locations
Troubleshooting: Insufficient Scopes
If you receive a 403 error with INSUFFICIENT_SCOPES, the OAuth connection doesn't have the required permissions. Create a new connection and ensure you grant all necessary permissions during OAuth authorization.