Build a seamless, zero-configuration integration between your app and Appstle Subscriptions. Once connected, your app gets a scoped API token for each merchant — no manual key exchange needed.Documentation Index
Fetch the complete documentation index at: https://appstleinc-aeca3e0a.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
- Frictionless merchant onboarding — one-click connect from either dashboard
- No API paywall — merchants don’t need a paid API plan to use your integration
- Scoped tokens — each merchant gets an isolated API key; revocable at any time
- Automatic cleanup — when a merchant disconnects or uninstalls, access is revoked instantly
How it works
The Partner Integration Framework uses a secure handshake protocol. Either side — your app or Appstle — can initiate the connection. Both flows end with your app receiving a scoped API token.Getting started
Step 1: Get onboarded
To get started, reach out to the Appstle team at support@appstle.com with the information below. Our team will set up your partner account and send you your credentials.What you’ll need to provide
| # | Field | Required? | Description | Example |
|---|---|---|---|---|
| 1 | App / Company Name | Required | Your app or company name. Displayed to merchants when they browse available partner integrations in the Appstle dashboard. | SearchPie |
| 2 | Partner ID | Required | A unique, lowercase slug that identifies your app in API URLs. Use only lowercase letters and hyphens. Once set, this cannot be changed. | search-pie |
| 3 | Base URL | Required | The HTTPS base URL where Appstle will send callback requests (connect, verify, approved). Must be publicly accessible — Appstle will not call HTTP or localhost URLs. | https://api.searchpie.com |
| 4 | Contact Email | Required | The email address where we’ll send your Partner Secret and any onboarding follow-ups. Use a team email if possible — the secret is shown only once. | dev-team@searchpie.com |
| 5 | Authentication Mode | Optional | How your API calls are authenticated. Choose one: Partner Secret (simpler — pass secret in a header) or HMAC-SHA256 (more secure — sign each request). Defaults to Partner Secret if not specified. | Partner Secret |
| 6 | Connect Mode | Optional | How merchant connections are established. Choose one: Nonce Handshake (full two-way verification — you receive an Appstle API key) or Simple Token Exchange (streamlined — you provide your own token for Appstle to call your API). Defaults to Nonce Handshake if not specified. | Nonce Handshake |
| 7 | Custom Endpoint Paths | Optional | By default, Appstle calls /appstle/connect and /appstle/verify on your Base URL. If you need different paths (e.g., /webhooks/appstle/connect), specify them here. | /webhooks/appstle/connect |
| 8 | Sync Path | Optional | If you want Appstle to push subscription data to your app (e.g., when contracts are created, updated, or cancelled), provide the path on your server where Appstle should send these payloads. | /appstle/sync |
| 9 | App Logo | Optional | A square logo (PNG or SVG, at least 128×128px) displayed next to your app name in the merchant’s Appstle dashboard. If not provided, a placeholder icon is used. | — |
What you’ll receive
Once onboarded, you’ll receive three values:| Credential | Example | Description |
|---|---|---|
| Partner ID | search-pie | Your unique identifier, as requested. Becomes part of the API URL. |
| Partner Secret | xK9mQ2vL... (48 chars) | A secret key used to authenticate your API calls. Treat this like a password. |
| Base URL | https://subscription-admin.appstle.com | Appstle’s API base URL. Same for all partners. |
Step 1b: Choose your authentication mode
Appstle supports two ways to authenticate partner API calls. Your auth mode is configured during onboarding.Option A: Partner Secret (default)
The simplest approach. Pass your secret in a header with every request:Option B: HMAC-SHA256
A more secure approach where requests are signed with a shared HMAC key. Instead of sending the secret directly, you compute a signature over the request body. Headers required:- Get the current Unix timestamp (seconds, not milliseconds)
- Concatenate the timestamp and the raw JSON request body:
timestamp + body - Compute HMAC-SHA256 of that string using your HMAC key
- Send the hex-encoded result in
X-Partner-Signature
- Partner Secret — simpler to implement, fine for most integrations
- HMAC-SHA256 — better security (secret never sent over the wire), recommended for high-volume or security-sensitive integrations
Step 1c: Choose your connect mode
Appstle supports two ways to establish merchant connections. Your connect mode is configured during onboarding.Option A: Nonce Handshake (default)
The full two-way verification flow described in this guide. Both sides verify each other using a one-time nonce. After the handshake, your app receives an Appstle API key (apst_...) to call Appstle’s External API.
Best for: Partners who want to read/write data in Appstle (subscription contracts, billing attempts, product swaps, etc.)
Option B: Simple Token Exchange
A streamlined flow where your app sends its own access token to Appstle (or Appstle calls your connect endpoint and you return one). No nonce, no verify endpoint needed. Appstle stores your token and uses it to call your API when needed. Best for: Partners where Appstle needs to call the partner’s API (e.g., syncing data to the partner’s platform), rather than the partner calling Appstle’s API. Key difference from Nonce Handshake: In Simple Token Exchange, your app provides its own access token to Appstle. Appstle stores this token and uses it to push data to your API (via yoursync_path — see Data sync below). Your app does not receive an Appstle API key in this mode.
How Simple Token Exchange works:
Partner-initiated:
access_token is stored securely but will not be activated until the merchant approves the connection from their Appstle dashboard. Once approved, Appstle calls your /appstle/approved endpoint to confirm (see Handling the approval callback)./appstle/connect endpoint with { "shop_domain": "..." }. Your app responds with:
Step 2: Understand the callback nonce
What is a callback nonce?
A nonce (number used once) is a random, single-use string that proves both sides of the connection are who they claim to be. It prevents replay attacks and ensures the handshake can’t be forged.Requirements
| Requirement | Detail |
|---|---|
| Length | At least 32 bytes (64 hex characters) |
| Randomness | Must be cryptographically random — do NOT use Math.random(), rand(), timestamps, or UUIDs |
| Single-use | Each nonce must be used exactly once, then deleted |
| Expiry | Nonces expire after 5 minutes on Appstle’s side. Your storage should also expire them. |
| Storage | Store temporarily with a TTL. Redis, DynamoDB, or any key-value store with expiry works. Database with a cleanup job is also fine. |
How to generate a nonce
Use your language’s cryptographically secure random number generator.How to store a nonce
Store the nonce temporarily, keyed by shop domain, with a 5-minute expiry. Delete it after verification.Step 3: Implement your endpoints
Your app must expose two HTTP endpoints that Appstle calls during the connection handshake. The paths default to/appstle/connect and /appstle/verify but can be customized during onboarding.
Both endpoints must:
- Accept
POSTrequests with a JSON body - Return JSON responses
- Be accessible over HTTPS (Appstle will not call HTTP endpoints)
- Respond within 10 seconds (or the request will time out)
Endpoint 1: POST /appstle/connect
When is this called? Appstle calls this when a merchant initiates the connection from Appstle’s dashboard (Flow B).
What does it receive?
| Field | Type | Description |
|---|---|---|
shop_domain | string | The merchant’s Shopify domain (e.g. cool-store.myshopify.com) |
app | string | Always "subscriptions" — identifies which Appstle app is connecting |
callback_url | string | The exact URL your app must call to complete the handshake |
callback_nonce | string | A one-time-use token generated by Appstle. Expires in 5 minutes. |
- Validate the shop — check that this
shop_domainexists in your system. If you don’t recognize the shop, return an error. - Store the nonce and callback URL — save
callback_nonceandcallback_urlassociated with thisshop_domain. You’ll need them to complete the handshake. - Call back to Appstle — either immediately (auto-approve) or after merchant confirmation, call the
callback_urlto complete the connection. See Completing the handshake below. - Return a success response — any
2xxstatus code tells Appstle the request was received.
Endpoint 2: POST /appstle/verify
When is this called? Appstle calls this when a merchant initiates the connection from your app’s dashboard (Flow A). Appstle is asking your app: “Did you actually send this nonce?”
What does it receive?
| Field | Type | Description |
|---|---|---|
shop_domain | string | The merchant’s Shopify domain |
callback_nonce | string | The nonce your app originally sent in the /connect call |
- Look up the stored nonce for this
shop_domain - Compare the
callback_noncefrom the request against your stored nonce - If they match: delete the stored nonce (it’s single-use) and return
{ "verified": true } - If they don’t match: return
{ "verified": false }
Step 4: Implement the connect flow (your dashboard)
Now build the merchant-facing “Connect Appstle Subscriptions” button in your app’s dashboard.Partner-initiated connect (Flow A) — step by step
This is the flow where the merchant clicks “Connect Appstle” in your dashboard.Merchant clicks "Connect Appstle" in your dashboard
Your app generates a cryptographically random nonce
shop_domain with a 5-minute TTL.Your app calls POST /api/partner/{id}/connect
shop_domain, the callback_nonce, and your Partner Secret.Appstle validates your Partner Secret
Appstle returns pending_merchant_approval
Merchant approves in their Appstle dashboard
/appstle/approved endpoint (see Handling the approval callback below). Pending requests expire after 30 days if not acted on.Appstle-initiated connect (Flow B) — step by step
This is the flow where the merchant clicks “Connect” in Appstle’s dashboard.Merchant clicks "Connect {YourApp}" in Appstle's dashboard
Appstle calls POST /api/partner/{id}/initiate-connect
Appstle generates a nonce (5-min TTL) and calls YOUR /appstle/connect
shop_domain, app, callback_url, and callback_nonce.Your /appstle/connect stores the nonce and callback_url
shop_domain for the verify step.Your app calls the callback_url (Appstle's /verify endpoint)
shop_domain, callback_nonce, and your Partner Secret.Appstle verifies the nonce and issues a scoped API key
access_token is returned in the response body.Completing the handshake (Flow B)
After your/appstle/connect endpoint receives the nonce and callback URL, your app completes the connection by calling Appstle’s verify endpoint:
Using the API token
After a successful connection, your app has anaccess_token (prefixed with apst_). For Appstle-initiated connections (Flow B), the token is returned immediately in the verify response. For partner-initiated connections (Flow A), the token is delivered asynchronously to your /appstle/approved endpoint after the merchant approves (see Handling the approval callback below).
Use this token exactly like a merchant API key — pass it in the X-API-Key header:
Token properties
| Property | Detail |
|---|---|
| Format | Starts with apst_ followed by 40 alphanumeric characters |
| Scope | One token per merchant per partner |
| Permission | READ_ONLY or READ_WRITE (set during partner onboarding) |
| Billing | Partner tokens bypass the paid API plan — merchants are never billed for partner API usage |
| Revocation | Revoked instantly when the merchant disconnects or uninstalls Appstle |
| Expiry | Tokens do not expire on their own. They remain valid until explicitly revoked. |
Available endpoints
Partner tokens grant access to the same External API endpoints as merchant API keys:- Subscription contracts —
GET /api/external/v2/subscription-contract-details - Customer subscriptions —
GET /api/external/v2/subscription-customers/{customerId} - Update subscription status —
PUT /api/external/v2/subscription-contracts-update-status(requires READ_WRITE) - Skip/Reschedule orders —
POST /api/external/v2/subscription-billing-attempts/skip-order/{id}(requires READ_WRITE) - Update line items —
PUT /api/external/v2/subscription-contracts-update-line-item(requires READ_WRITE) - Apply discounts —
POST /api/external/v2/subscription-contracts-apply-discount(requires READ_WRITE) - And all other
/api/external/v2/*endpoints
Data sync (push model)
Some integrations work best when Appstle pushes data to your app, rather than your app pulling from Appstle’s API. For example, a search platform might need Appstle to push subscription data so it can be indexed alongside other store data.How it works
During onboarding, you can configure async_path on your server (e.g., /appstle/sync). When subscription events occur (new subscriptions, cancellations, billing attempts, etc.), Appstle calls your endpoint with the relevant data.
| Config Field | Example | Description |
|---|---|---|
sync_path | /appstle/sync | Your endpoint where Appstle pushes subscription data |
disconnect_path | /appstle/disconnect | Your endpoint called when a merchant disconnects |
Authentication
When Appstle calls your endpoints, it authenticates using the auth mode configured for your partner:- Partner Secret mode: No additional headers (your endpoints are responsible for validating the source — consider IP allowlisting)
- HMAC-SHA256 mode (recommended): Appstle signs every request with
X-Partner-TimestampandX-Partner-Signatureheaders. Your app should verify the HMAC signature to confirm the request came from Appstle.
Pull vs push — which model do I need?
| Model | Connect Mode | Your App Calls Appstle? | Appstle Calls Your App? | Use Case |
|---|---|---|---|---|
| Pull (default) | Nonce Handshake | Yes (via apst_ API key) | No | Helpdesks, CRMs reading subscription data on demand |
| Push | Simple Token Exchange | No | Yes (via your token + sync_path) | Search platforms, analytics tools that index data |
| Bidirectional | Nonce Handshake + sync_path | Yes | Yes | Full two-way integrations |
Disconnecting
Merchant disconnects from Appstle
Merchants can disconnect your integration anytime from Appstle Dashboard → Settings → Partner Connections. When they do:- Your API token for that merchant is revoked immediately
- Subsequent API calls will return
401 Unauthorized - Appstle sends a disconnect webhook to your app (if you configured a
disconnect_pathduring onboarding — see below) - Your app should handle this gracefully and show a “Reconnect” option
401 responses and update your UI to show the connection as disconnected:
Disconnect webhook (recommended)
If you configure adisconnect_path during onboarding (e.g., /appstle/disconnect), Appstle will call your endpoint whenever a merchant disconnects — whether they disconnect from the Appstle dashboard, from your app, or by uninstalling Appstle entirely.
Request body from Appstle:
X-Partner-Timestamp, X-Partner-Signature) so you can verify it came from Appstle.
Your app should:
- Mark the connection as disconnected in your database
- Clean up any stored Appstle tokens for this shop
- Return any
2xxstatus code
401 responses from the Appstle API as a fallback signal that the connection was revoked.Partner disconnects programmatically
Your app can disconnect a merchant using your partner authentication (Partner Secret or HMAC-SHA256):Check connection status
Verify a merchant’s connection status. Partners can authenticate with their Partner Secret or HMAC signature:| Status | Meaning |
|---|---|
active | Connected and working — API token is valid |
pending_merchant_approval | Partner-initiated connect is awaiting merchant approval |
rejected | Merchant rejected the connection request |
expired | The pending request expired (30-day window) — partner must initiate a new connection |
not_connected | No connection exists for this partner + shop |
Handling the approval callback
When a merchant approves a partner-initiated connection, Appstle delivers the API token by calling an endpoint on your server. This applies to partner-initiated connections only — Appstle-initiated connections (Flow B) return the token immediately.Endpoint: POST /appstle/approved
The path defaults to /appstle/approved but can be customized during onboarding (configured as approval_callback_path).
Request body from Appstle (Nonce Handshake mode):
2xx status code with a JSON body (e.g., { "success": true }). If your endpoint returns a non-2xx status (e.g., 401 Unauthorized), the connection is still approved on Appstle’s side, but your app won’t know — see What if the callback fails? below.
If your partner uses HMAC-SHA256 auth, the callback includes signed headers (X-Partner-Timestamp, X-Partner-Signature) so you can verify it came from Appstle.
What if the callback fails?
If your endpoint is unreachable or returns an error, the connection is still approved on Appstle’s side. The API token exists and is valid. Your app can:- Poll the status endpoint — check
GET /api/partner/{id}/status?shop_domain=...until the status isactive - Retry from Appstle’s side — currently, Appstle does not automatically retry the callback. Contact support if you need the token re-delivered.
What if the merchant rejects?
If the merchant clicks “Reject,” the connection status changes torejected and Appstle notifies your app via the disconnect webhook (if configured). Your app should handle this gracefully — show the merchant that the connection was not approved.
Error handling
All partner endpoints return structured error responses:Error codes
| Error Code | HTTP Status | When It Happens | What To Do |
|---|---|---|---|
PARTNER_NOT_FOUND | 400 | Your Partner ID is wrong, or the partner has been deactivated | Double-check your Partner ID. Contact Appstle if unexpected. |
TOKEN_INVALID | 400 | Auth failed: X-Partner-Secret is wrong, or HMAC signature is invalid, or timestamp is >5 min off | Verify your secret or HMAC key. Check for trailing whitespace. For HMAC: ensure server clock is synced (NTP) and you’re signing timestamp + body exactly. |
SHOP_NOT_FOUND | 400 | The shop doesn’t have Appstle Subscriptions installed | Tell the merchant to install Appstle Subscriptions first. |
ALREADY_CONNECTED | 400 | An active connection already exists for this partner + shop | Call disconnect first, then reconnect. Or skip — you’re already connected. |
VERIFICATION_FAILED | 400 | Nonce didn’t match, expired (>5 min), or your /verify endpoint returned false | Generate a fresh nonce and try again. Check your nonce storage logic. |
NOT_CONNECTED | 400 | Trying to disconnect or check status, but no active connection exists | The merchant may have already disconnected from their side. |
PARTNER_UNREACHABLE | 400 | Appstle couldn’t reach your /appstle/connect or /appstle/verify endpoint | Check your endpoint URL is correct, HTTPS, and publicly accessible. Check your server logs. |
Security checklist
Before going live, verify all of these:- Partner Secret / HMAC Key is stored in environment variables or a secrets manager — not hardcoded in source code
- Nonces are generated using a cryptographically secure random generator (
crypto.randomBytes,secrets.token_hex,SecureRandom, etc.) - Nonces are stored with a TTL (≤ 5 minutes) and deleted after verification
- Nonces are compared using a constant-time comparison to prevent timing attacks (most frameworks do this by default for string equality)
- Endpoints are served over HTTPS — Appstle will not call HTTP endpoints
-
shop_domainis validated in your/appstle/connectand/appstle/verifyendpoints — reject domains you don’t recognize - Access tokens are stored encrypted at rest (or in a secrets manager)
- 401 responses are handled gracefully — show a “Reconnect” option, don’t break silently
- Error responses from Appstle are logged for debugging
- (HMAC only) Server clock is synced via NTP — timestamps more than 5 minutes off will be rejected
- (If using disconnect webhook) Your
/appstle/disconnectendpoint cleans up stored tokens and marks the connection as inactive
Complete example: partner-initiated flow
FAQ
Can a merchant have multiple partner connections?
Can a merchant have multiple partner connections?
What happens if a merchant uninstalls Appstle Subscriptions?
What happens if a merchant uninstalls Appstle Subscriptions?
Can I change my partner's permission level (READ_ONLY vs READ_WRITE) after onboarding?
Can I change my partner's permission level (READ_ONLY vs READ_WRITE) after onboarding?
What's the rate limit for partner API calls?
What's the rate limit for partner API calls?
429 Too Many Requests, implement exponential backoff.How do I test the integration before going live?
How do I test the integration before going live?
What if the nonce expires before I can complete the handshake?
What if the nonce expires before I can complete the handshake?
Do I need to implement both Flow A and Flow B?
Do I need to implement both Flow A and Flow B?
/appstle/approved endpoint to receive API tokens after merchant approval (Flow A).Can I reconnect a merchant without them doing anything?
Can I reconnect a merchant without them doing anything?
Why does partner-initiated connect require merchant approval?
Why does partner-initiated connect require merchant approval?
How long does a pending approval last?
How long does a pending approval last?
What happens if the merchant rejects the connection?
What happens if the merchant rejects the connection?
rejected and your app is notified via the disconnect webhook (if configured). The merchant can be asked to reconnect later if they change their mind — your app can initiate a new connection request.Need help?
- Partner onboarding & technical support: support@appstle.com
- Integration guide: Third-party integration guide (for direct API key usage)