Shopify API
The Shopify API enables Shopify merchants and integration partners (such as Avada Joy Loyalty, Yotpo Reviews, LoyaltyLion, and Klaviyo) to programmatically plant trees, recover ocean plastic, trigger charity donations, fetch impact statistics, process reversals, and retrieve verification evidence.
Authentication & Headers
Section titled “Authentication & Headers”All requests to the Shopify API require authentication via HTTP headers.
| Header Name | Type | Required | Description |
|---|---|---|---|
api_key* | string | Yes | Your Shopify API Key (PROD-xxxx... or TEST-xxxx...). |
shop_name* | string | Yes | Your Shopify store domain (e.g., my-store.myshopify.com). |
user_id | string | Optional | Store user identifier. If present, user_id overrides shop_name. |
Content-Type | string | Yes | application/json (required for POST requests). |
Idempotency-Key | string | Optional | Unique key to safely retry write operations without duplicate executions. |
Verify Connection
Section titled “Verify Connection”GET https://sprout-app.thegoodapi.com/app/api/verify
Verifies the provided API key and returns active key mode (PROD vs TEST), store status, and enabled features. Rejects Standalone API keys with HTTP 401 WRONG_KEY_TYPE.
Headers
Section titled “Headers”| Header Name | Type | Required | Description |
|---|---|---|---|
api_key* | string | Yes | Your Shopify API Key |
shop_name* | string | Yes | Your Shopify store domain |
Response — 200 OK
Section titled “Response — 200 OK”{ "status": "active", "shop_domain": "my-store.myshopify.com", "key_mode": "PROD", "features": { "tree_planting": true, "plastic_removal": true, "donations": true }}curl -X GET "https://sprout-app.thegoodapi.com/app/api/verify" \ -H "api_key: PROD-8f92a1b3-4c56-7d89" \ -H "shop_name: my-store.myshopify.com"const response = await fetch("https://sprout-app.thegoodapi.com/app/api/verify", { method: "GET", headers: { "api_key": "PROD-8f92a1b3-4c56-7d89", "shop_name": "my-store.myshopify.com" }});const data = await response.json();Plant Trees
Section titled “Plant Trees”POST https://sprout-app.thegoodapi.com/app/api/plant
Trigger tree planting for a customer order or loyalty reward redemption.
Request Body
Section titled “Request Body”| Parameter | Type | Required | Description |
|---|---|---|---|
trees | integer | Yes | Number of trees to plant. |
customer_name | string | Optional | Customer full name for attribution and customer-scoped queries. |
order_id | string | Optional | Shopify Order ID or order reference. |
notes | string | Optional | Integration notes or redemption details. |
Response — 200 OK
Section titled “Response — 200 OK”{ "status": "success", "trees_planted": 5, "customer_name": "Jane Doe", "order_id": "1001"}curl -X POST "https://sprout-app.thegoodapi.com/app/api/plant" \ -H "Content-Type: application/json" \ -H "api_key: PROD-8f92a1b3-4c56-7d89" \ -H "shop_name: my-store.myshopify.com" \ -d '{ "trees": 5, "customer_name": "Jane Doe", "order_id": "1001", "notes": "Loyalty Points Redemption" }'const response = await fetch("https://sprout-app.thegoodapi.com/app/api/plant", { method: "POST", headers: { "Content-Type": "application/json", "api_key": "PROD-8f92a1b3-4c56-7d89", "shop_name": "my-store.myshopify.com" }, body: JSON.stringify({ trees: 5, customer_name: "Jane Doe", order_id: "1001" })});const data = await response.json();Get Planted Trees History
Section titled “Get Planted Trees History”GET https://sprout-app.thegoodapi.com/app/api/plant
Query planted tree records with support for date range filtering and cursor pagination.
Query Parameters
Section titled “Query Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
customer_name | string | Optional | Filter by customer name (supports substring & case-insensitive matching). |
customer_email | string | Optional | Filter by customer email address (case-insensitive). |
email | string | Optional | Alias for customer_email. |
customer_id | string / integer | Optional | Filter by numeric customer ID or string ID. |
customer | string | Optional | Flexible customer filter (matches customer name, email, or ID). |
order_id | string | Optional | Filter by order ID (supports # prefix matching, e.g. 1001 matches #1001). |
start_date | string | Optional | Filter records created on or after date (YYYY-MM-DD). |
end_date | string | Optional | Filter records created before date (YYYY-MM-DD). |
limit | integer | Optional | Max items to return (default: 20, max: 100). |
after_created_at | string | Optional | Cursor timestamp for fetching next page. |
Response — 200 OK
Section titled “Response — 200 OK”{ "trees": [ { "id": "tree_66a9b1c2d3e4", "count": 5, "customer_name": "Jane Doe", "order_id": "1001", "created_at": "2026-07-27T12:00:00Z" } ], "count": 1, "has_more": false, "next_cursor": ""}curl -X GET "https://sprout-app.thegoodapi.com/app/api/plant?customer_name=Jane+Doe&limit=20" \ -H "api_key: PROD-8f92a1b3-4c56-7d89" \ -H "shop_name: my-store.myshopify.com"const response = await fetch("https://sprout-app.thegoodapi.com/app/api/plant?customer_name=Jane+Doe&limit=20", { method: "GET", headers: { "api_key": "PROD-8f92a1b3-4c56-7d89", "shop_name": "my-store.myshopify.com" }});const data = await response.json();Recover Ocean Plastic
Section titled “Recover Ocean Plastic”POST https://sprout-app.thegoodapi.com/app/api/plastic
Trigger ocean plastic bottle recovery for a customer order or reward redemption.
Request Body
Section titled “Request Body”| Parameter | Type | Required | Description |
|---|---|---|---|
bottles | integer | Yes | Number of plastic bottles to recover. |
customer_name | string | Optional | Customer full name for attribution. |
order_id | string | Optional | Shopify Order ID. |
notes | string | Optional | Integration notes. |
Response — 200 OK
Section titled “Response — 200 OK”{ "status": "success", "bottles_rescued": 50, "customer_name": "Jane Doe", "order_id": "1001"}curl -X POST "https://sprout-app.thegoodapi.com/app/api/plastic" \ -H "Content-Type: application/json" \ -H "api_key: PROD-8f92a1b3-4c56-7d89" \ -H "shop_name: my-store.myshopify.com" \ -d '{ "bottles": 50, "customer_name": "Jane Doe", "order_id": "1001" }'const response = await fetch("https://sprout-app.thegoodapi.com/app/api/plastic", { method: "POST", headers: { "Content-Type": "application/json", "api_key": "PROD-8f92a1b3-4c56-7d89", "shop_name": "my-store.myshopify.com" }, body: JSON.stringify({ bottles: 50, customer_name: "Jane Doe", order_id: "1001" })});const data = await response.json();Get Plastic Recovery History
Section titled “Get Plastic Recovery History”GET https://sprout-app.thegoodapi.com/app/api/plastic
Query ocean plastic recovery records with date range filtering and cursor pagination.
Query Parameters
Section titled “Query Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
customer_name | string | Optional | Filter by customer name (supports substring & case-insensitive matching). |
customer_email | string | Optional | Filter by customer email address (case-insensitive). |
email | string | Optional | Alias for customer_email. |
customer_id | string / integer | Optional | Filter by numeric customer ID or string ID. |
customer | string | Optional | Flexible customer filter (matches customer name, email, or ID). |
order_id | string | Optional | Filter by order ID (supports # prefix matching). |
start_date | string | Optional | Filter records created on or after date (YYYY-MM-DD). |
end_date | string | Optional | Filter records created before date (YYYY-MM-DD). |
limit | integer | Optional | Max items to return (default: 20). |
after_created_at | string | Optional | Cursor timestamp for fetching next page. |
Response — 200 OK
Section titled “Response — 200 OK”{ "plastics": [ { "id": "plastic_77b8c9d0e1", "count": 50, "customer_name": "Jane Doe", "order_id": "1001", "created_at": "2026-07-27T12:05:00Z" } ], "count": 1, "has_more": false, "next_cursor": ""}Trigger Charity Donation
Section titled “Trigger Charity Donation”POST https://sprout-app.thegoodapi.com/app/api/charity/donate
Trigger a charitable donation allocation for a customer purchase or loyalty redemption.
Request Body
Section titled “Request Body”| Parameter | Type | Required | Description |
|---|---|---|---|
charity_id | string | Yes | Non-profit charity partner ID. |
amount_dollars | number | Yes | Donation amount in USD (supports amount, donation_amount, or amount_dollars). |
customer_name | string | Optional | Customer full name for attribution. |
order_id | string | Optional | Shopify Order ID. |
Response — 200 OK
Section titled “Response — 200 OK”{ "status": "success", "charity_id": "charity_trees_for_future", "amount": 5.00, "mode": "PROD"}curl -X POST "https://sprout-app.thegoodapi.com/app/api/charity/donate" \ -H "Content-Type: application/json" \ -H "api_key: PROD-8f92a1b3-4c56-7d89" \ -H "shop_name: my-store.myshopify.com" \ -d '{ "charity_id": "charity_trees_for_future", "amount_dollars": 5.00, "customer_name": "Jane Doe" }'const response = await fetch("https://sprout-app.thegoodapi.com/app/api/charity/donate", { method: "POST", headers: { "Content-Type": "application/json", "api_key": "PROD-8f92a1b3-4c56-7d89", "shop_name": "my-store.myshopify.com" }, body: JSON.stringify({ charity_id: "charity_trees_for_future", amount_dollars: 5.00, customer_name: "Jane Doe" })});const data = await response.json();Get Impact Statistics
Section titled “Get Impact Statistics”GET https://sprout-app.thegoodapi.com/app/api/impact/stats
Retrieve store-wide or customer-scoped lifetime impact totals (trees, plastic_bottles, donations, co2_kg).
Query Parameters
Section titled “Query Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
customer_name | string | Optional | Filter impact stats by customer name (supports substring & case-insensitive matching). |
customer_email | string | Optional | Filter impact stats by customer email (case-insensitive). |
email | string | Optional | Alias for customer_email. |
customer_id | string / integer | Optional | Filter impact stats by numeric customer ID or string ID. |
customer | string | Optional | Flexible customer filter (matches customer name, email, or ID). |
Response — 200 OK
Section titled “Response — 200 OK”{ "trees": 15, "plastic_bottles": 100, "donations": 10.00, "co2_kg": 300.0, "customer_scoped": true}curl -X GET "https://sprout-app.thegoodapi.com/app/api/impact/stats?customer_name=Jane+Doe" \ -H "api_key: PROD-8f92a1b3-4c56-7d89" \ -H "shop_name: my-store.myshopify.com"const response = await fetch("https://sprout-app.thegoodapi.com/app/api/impact/stats?customer_name=Jane+Doe", { method: "GET", headers: { "api_key": "PROD-8f92a1b3-4c56-7d89", "shop_name": "my-store.myshopify.com" }});const data = await response.json();Process Impact Refunds & Reversals
Section titled “Process Impact Refunds & Reversals”POST https://sprout-app.thegoodapi.com/app/api/refund
Reverses tree, plastic, or donation allocations when an order or loyalty redemption is cancelled. Restores tree/plastic units directly back to the merchant’s top-up balance.
Request Body
Section titled “Request Body”| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Unit type to reverse (tree, plastic, or donation). |
quantity | integer | Yes | Quantity of units to reverse. |
customer_name | string | Optional | Customer name associated with the original allocation. |
reason | string | Optional | Reason for reversal. |
Response — 200 OK
Section titled “Response — 200 OK”{ "status": "success", "mode": "PROD", "refunded_type": "tree", "count": 5}curl -X POST "https://sprout-app.thegoodapi.com/app/api/refund" \ -H "Content-Type: application/json" \ -H "api_key: PROD-8f92a1b3-4c56-7d89" \ -H "shop_name: my-store.myshopify.com" \ -d '{ "type": "tree", "quantity": 5, "customer_name": "Jane Doe", "reason": "Customer cancelled loyalty reward" }'const response = await fetch("https://sprout-app.thegoodapi.com/app/api/refund", { method: "POST", headers: { "Content-Type": "application/json", "api_key": "PROD-8f92a1b3-4c56-7d89", "shop_name": "my-store.myshopify.com" }, body: JSON.stringify({ type: "tree", quantity: 5, customer_name: "Jane Doe", reason: "Customer cancelled loyalty reward" })});const data = await response.json();Fetch Verification Evidence
Section titled “Fetch Verification Evidence”GET https://sprout-app.thegoodapi.com/app/api/evidence
Delegates directly to treeapi (/evidence endpoint) to retrieve planting evidence photos/videos, region metadata, and timeline events matching target impact dates (unrelated to certificates).
Query Parameters
Section titled “Query Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
tree_id | string | Optional | Tree record ID (tree_id, id, or tree). |
impact_type | string | Optional | Impact type (trees, default: trees). |
created_at | string | Optional | Target impact date timestamp (YYYY-MM-DD or ISO timestamp). |
tree_date | string | Optional | Alias for created_at. |
project_public_id | string | Optional | Filter by project public ID. |
region | string | Optional | Filter by region name. |
Response — 200 OK
Section titled “Response — 200 OK”{ "tree_id": "test_tree_1001", "impact_type": "trees", "created_at": "2024-05-15T10:00:00Z", "region": "Kenya", "evidence_count": 5, "timeline": [ { "event": "Planted", "status": "Completed" } ]}curl -X GET "https://sprout-app.thegoodapi.com/app/api/evidence?tree_id=test_tree_1001" \ -H "api_key: PROD-8f92a1b3-4c56-7d89" \ -H "shop_name: my-store.myshopify.com"const response = await fetch("https://sprout-app.thegoodapi.com/app/api/evidence?impact_type=trees&created_at=2024-05-15T10:00:00Z", { method: "GET", headers: { "api_key": "PROD-8f92a1b3-4c56-7d89", "shop_name": "my-store.myshopify.com" }});const data = await response.json();Error Codes
Section titled “Error Codes”| Error Code | HTTP Status | Description | Action / Resolution |
|---|---|---|---|
UNAUTHORIZED | 401 Unauthorized | Missing required api_key or shop_name/user_id headers. | Include valid authentication headers. |
WRONG_KEY_TYPE | 401 Unauthorized | Standalone API key used on Shopify API endpoint. | Use a store Prod (PROD-) or Test (TEST-) API key. |
INVALID_KEY | 401 Unauthorized | Invalid API key provided for the store. | Check API key in Shopify Admin -> App -> Settings. |
INSUFFICIENT_BUDGET | 402 Payment Required | Merchant top-up budget is exhausted. | Top up balance in Shopify Admin -> App -> Billing. |
INVALID_SHOP | 401 Unauthorized | Store domain not found or uninstalled. | Verify shop_name domain spelling. |
INVALID_PARAMETER | 400 Bad Request | Invalid JSON payload or negative quantity. | Ensure valid JSON request body. |