{"openapi":"3.1.0","info":{"title":"Agentic Sellar API","version":"1.0.0","description":"Every platform capability is available over REST. Authenticate with an API key (Authorization: Bearer as_...) minted at POST /api/organizations/{orgId}/api-keys. The two Amazon OAuth flows require a human in the browser; everything else is fully programmatic."},"servers":[{"url":"https://agenticsellar.com"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key (as_ prefix) or omit for session cookie"}}},"paths":{"/api/health":{"get":{"summary":"Liveness and dependency check","tags":["System"],"security":[],"parameters":[],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/openapi.json":{"get":{"summary":"This API description as an OpenAPI 3.1 document","tags":["System"],"description":"Agents should load this first to discover available operations.","security":[],"parameters":[],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/auth/signup":{"post":{"summary":"Create an account and organization","tags":["Auth"],"security":[],"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","description":"string (required)"},"password":{"type":"string","description":"string (required, min 12 chars with complexity)"},"name":{"type":"string","description":"string"},"organizationName":{"type":"string","description":"string"}}}}}},"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/auth/accept-invite":{"get":{"summary":"Validate a team invite token","tags":["Auth"],"security":[],"parameters":[{"name":"token","in":"query","required":true,"description":"Invite token","schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}},"post":{"summary":"Accept an invite and create the member account","tags":["Auth"],"security":[],"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","description":"string (required)"},"name":{"type":"string","description":"string"},"password":{"type":"string","description":"string (required)"}}}}}},"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/api-keys":{"get":{"summary":"List API keys (prefix + metadata only)","tags":["API keys"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}},"post":{"summary":"Mint a new API key — the raw token is returned once","tags":["API keys"],"description":"Bootstrap: create the first key while logged into the dashboard, or via session cookie.","security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"string (required, ≤80 chars)"},"expiresInDays":{"type":"string","description":"number 1-365 (optional)"}}}}}},"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/api-keys/{keyId}":{"delete":{"summary":"Revoke an API key immediately","tags":["API keys"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}},{"name":"keyId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/amazon/ads/connect":{"get":{"summary":"Start the Amazon Ads OAuth flow (browser redirect)","tags":["Amazon connections"],"description":"Browser flow — an agent should hand this URL to a human for consent.","security":[{"bearerAuth":[]}],"parameters":[{"name":"region","in":"query","required":false,"description":"na | eu | fe (default na)","schema":{"type":"string"}},{"name":"next","in":"query","required":false,"description":"Internal path to return to after OAuth","schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/amazon/sp/connect":{"get":{"summary":"Start the Selling Partner API OAuth flow (browser redirect)","tags":["Amazon connections"],"description":"Browser flow — requires Seller Central login + consent.","security":[{"bearerAuth":[]}],"parameters":[{"name":"region","in":"query","required":false,"description":"na | eu | fe (default na)","schema":{"type":"string"}},{"name":"next","in":"query","required":false,"description":"Internal path to return to after OAuth","schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/amazon/ads/pending-profiles":{"get":{"summary":"List advertising profiles available to the pending OAuth grant","tags":["Amazon connections"],"security":[],"parameters":[],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/amazon/ads/select":{"post":{"summary":"Bind selected advertising profiles; triggers the 93-day backfill","tags":["Amazon connections"],"security":[],"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"profileIds":{"type":"string","description":"string[] (required)"}}}}}},"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/credentials/amazon":{"get":{"summary":"List connected Amazon profiles and their connection status","tags":["Amazon connections"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/credentials/amazon/{credentialId}":{"delete":{"summary":"Disconnect one Amazon profile binding","tags":["Amazon connections"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}},{"name":"credentialId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/ads-profiles":{"get":{"summary":"List every profile the stored Ads token can access","tags":["Amazon connections"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}},"patch":{"summary":"Switch the bound advertising profile","tags":["Amazon connections"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"profileId":{"type":"string","description":"string (required)"}}}}}},"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/credentials/llm":{"get":{"summary":"Get active LLM provider metadata (never the key)","tags":["LLM"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}},"post":{"summary":"Store the org's LLM API key (BYOLLM)","tags":["LLM"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"provider":{"type":"string","description":"anthropic | openai | google"},"apiKey":{"type":"string","description":"string (required)"}}}}}},"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/agent/config":{"get":{"summary":"Get agent goals, tier, guardrails, and kill-switch state","tags":["Agent"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}},"put":{"summary":"Update agent configuration (partial)","tags":["Agent"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"goalMode":{"type":"string","description":"balanced | growth | profitability"},"targetAcos":{"type":"string","description":"string decimal e.g. '0.3'"},"targetTacos":{"type":"string","description":"string decimal (optional)"},"maxDailyAutoExecutes":{"type":"string","description":"string int"},"maxBidChangePct":{"type":"string","description":"string decimal"},"isActive":{"type":"string","description":"'true' | 'false'"},"isPaused":{"type":"string","description":"'true' | 'false' (kill switch)"},"notifyWebhookUrl":{"type":"string","description":"string (optional)"},"notifyEmail":{"type":"string","description":"string (optional)"}}}}}},"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/agent/permissions":{"get":{"summary":"List per-category action permission levels","tags":["Agent"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}},"put":{"summary":"Set the permission level for one action category","tags":["Agent"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"actionCategory":{"type":"string","description":"bid_adjustment | keyword_addition | keyword_negation | campaign_creation | campaign_pause | budget_change | placement_change"},"permissionLevel":{"type":"string","description":"auto_execute | require_approval | blocked"}}}}}},"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/actions/pending":{"get":{"summary":"List actions waiting for approval","tags":["Actions"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/actions/{actionId}/approve":{"post":{"summary":"Approve and synchronously execute one action against Amazon","tags":["Actions"],"description":"Stays pending if Amazon execution fails — safe to retry.","security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}},{"name":"actionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/actions/{actionId}/reject":{"post":{"summary":"Reject a pending action","tags":["Actions"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}},{"name":"actionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/actions/bulk-approve":{"post":{"summary":"Approve and execute up to 100 actions; per-action results","tags":["Actions"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"actionIds":{"type":"string","description":"string[] (required, ≤100)"}}}}}},"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/explore":{"get":{"summary":"Unified data explorer — commercial and advertising levels","tags":["Data"],"description":"Same grammar as the dashboard explorer's URL (/dashboard/explore?…) — any UI view is reconstructable via this endpoint and vice versa. Metric definitions: ACoS = spend/sales; ROAS = sales/spend; TACoS = spend ÷ total account sales (order metrics, account-level denominator); organicSales = total sales − ad-attributed sales. All IDs are Amazon-native. noSales/minSpend filter rows only; summary always reflects the full filtered scope. summary.wastedSpend/wastedTerms = total spend and count of (term × marketplace) window aggregates with zero attributed orders — the same rows level=searchTerm&noSales=true lists, so the headline and its drill-down reconcile; recent days can still attribute and leave the bucket. Level extras: campaign rows carry topOfSearchImpressionShare (SP only, 0-1 fraction, impressions-weighted over the window; null for SB/SD). searchTerm rows carry impressionShare and impressionRank from the Ads V1 impression-share plane — the term's ACCOUNT-WIDE share of impressions vs all advertisers (0-1, impressions-weighted) and the best (minimum) rank in the window; both null until that plane has synced. They are account-per-marketplace metrics, not campaign-scoped — Amazon's search-term IS metrics don't break down by campaign.","security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}},{"name":"level","in":"query","required":false,"description":"Aggregation level: brand | family | product | productCampaign (requires asin) | campaign (API default) | adGroup | target | searchTerm. Commercial levels return the /products response shape and accept its sort keys, focus, brand, and parentAsin filters; profile is advertising-only. adGroup/target aggregate keyword-attributed metrics, so SB/SD contribute only at campaign level.","schema":{"type":"string"}},{"name":"focus","in":"query","required":false,"description":"Commercial levels: comma-separated child ASINs","schema":{"type":"string"}},{"name":"brand","in":"query","required":false,"description":"Commercial levels: filter by brand","schema":{"type":"string"}},{"name":"parentAsin","in":"query","required":false,"description":"Commercial levels: filter by parent ASIN","schema":{"type":"string"}},{"name":"from","in":"query","required":false,"description":"Start date YYYY-MM-DD (default 30 days ago)","schema":{"type":"string"}},{"name":"to","in":"query","required":false,"description":"End date YYYY-MM-DD (default today)","schema":{"type":"string"}},{"name":"profile","in":"query","required":false,"description":"Scope to one Amazon Ads profile ID","schema":{"type":"string"}},{"name":"mkt","in":"query","required":false,"description":"Scope to one marketplace ID, e.g. ATVPDKIKX0DER","schema":{"type":"string"}},{"name":"type","in":"query","required":false,"description":"sponsoredProducts | sponsoredBrands | sponsoredDisplay","schema":{"type":"string"}},{"name":"state","in":"query","required":false,"description":"enabled | paused | archived","schema":{"type":"string"}},{"name":"q","in":"query","required":false,"description":"Substring match on the level's label","schema":{"type":"string"}},{"name":"campaignId","in":"query","required":false,"description":"Drill scope: Amazon campaign ID","schema":{"type":"string"}},{"name":"asin","in":"query","required":false,"description":"Product scope: restrict every level to the campaigns advertising this ASIN (resolved via the ad-group↔ASIN mapping). The account plane (total/organic/TACoS) is omitted under this scope — order metrics cannot be product-scoped.","schema":{"type":"string"}},{"name":"adGroupId","in":"query","required":false,"description":"Drill scope: Amazon ad group ID","schema":{"type":"string"}},{"name":"keywordId","in":"query","required":false,"description":"Drill scope: Amazon keyword/target ID","schema":{"type":"string"}},{"name":"noSales","in":"query","required":false,"description":"true → only rows with zero orders (wasted spend)","schema":{"type":"string"}},{"name":"minSpend","in":"query","required":false,"description":"Only rows with at least this much spend","schema":{"type":"string"}},{"name":"sort","in":"query","required":false,"description":"Ad levels: name|impressions|clicks|spend|sales|orders|acos (default -spend). Commercial levels: netSales|organicSales|units|adSpend|adSales|acos|tacos|netProceeds|totalSales|refunds|grossProfit|netProfit|asin (default -netSales). Prefix - for descending.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"0-500 (default 100); 0 returns summary only","schema":{"type":"string"}},{"name":"offset","in":"query","required":false,"description":"Pagination offset","schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/campaigns/{campaignId}/products":{"get":{"summary":"Products a campaign advertises — the inverse of /explore?asin=","tags":["Explore"],"description":"campaignId is the Amazon-native campaign id (same as /explore rows). Each product carries asin/title/image plus its spend/sales inside the campaign for the window (SP/SD, per-ASIN report). SB creative ASINs list with null spend/sales — SB attribution is campaign-level.","security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}},{"name":"campaignId","in":"path","required":true,"schema":{"type":"string"}},{"name":"from","in":"query","required":false,"description":"Start date YYYY-MM-DD (default 30 days ago)","schema":{"type":"string"}},{"name":"to","in":"query","required":false,"description":"End date YYYY-MM-DD (default today)","schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}":{"get":{"summary":"Org profile + preferences (reporting currency, plan)","tags":["Organization"],"description":"displayCurrency null = auto (currency of the largest connected marketplace). Combined-marketplace money in /explore, /kpi and /products is converted into this currency at daily ECB rates.","security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}},"patch":{"summary":"Update org preferences — currently displayCurrency","tags":["Organization"],"description":"Body: { displayCurrency: string | null }. Null = auto. Must be one of the supported ECB-covered currencies; unsupported codes 400.","security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}},"delete":{"summary":"GDPR deletion: nuke credentials now, cascade after 30 days","tags":["Organization"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}},{"name":"confirm","in":"query","required":true,"description":"Must be 'yes-i-am-sure'","schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/objects/{objectType}/{objectId}/activity":{"get":{"summary":"Glass-box timeline: agent actions + measured outcomes for one object","tags":["Data"],"description":"objectType: campaign | keyword. objectId accepts the Amazon-native ID (preferred) or internal UUID. Campaign timelines include actions on the campaign's keywords. Each item carries the change (from→to), the agent's reasoning, approval status, and the 14-day pre/post outcome once attribution has run.","security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}},{"name":"objectType","in":"path","required":true,"schema":{"type":"string"}},{"name":"objectId","in":"path","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Max 200 (default 50)","schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/products":{"get":{"summary":"Per-ASIN subject tree — ad spend/sales/ACoS, plus sales, TACoS, profit, margin","tags":["Data"],"description":"Same grammar as the /dashboard Explore page. Ad columns (adSpend, adSales, acos, adOrders, adUnits, impressions, clicks, ctr, cvr, cpc) come from the Amazon Ads advertised-product report and are live as soon as Ads is connected — adsAvailable=true. Commercial columns come from SP-API Data Kiosk Economics — economicsAvailable=false until the Selling Partner Insights role supplies data. P&L stack per row and in summary: totalSales (gross, pre-refund) | refunds/refundedUnits | netSales (post-refund) | amazonFees (FeeSummary total) | grossProfit = netSales − amazonFees − cogs | grossMargin | netProfit = grossProfit − adSpend | netMargin | roi = netProfit ÷ cogs | asp = totalSales ÷ units | velocity = units/day | ppcShare = adUnits ÷ units (true ad-attributed units from the advertised-product reports: SP unitsSoldClicks7d + SD unitsSold, capped at 1). ACoS = ad spend ÷ ad sales; TACoS = ad spend ÷ total sales. summary.adSpend is the per-ASIN-attributed total (advertised-product reports); summary.unattributedAdSpend is the honest remainder — campaign-level spend across all ad types (same scope/window/FX) minus that attributed total. It is structural (Sponsored Brands has no per-ASIN report, so SB spend can never attribute to a product) plus report-restatement drift, and can be slightly negative when Amazon restates the per-ASIN report ahead of the campaign one; attributed + unattributed always reconciles to the campaign total. Traffic columns (sessions, pageViews, unitSessionPct = units ÷ sessions) come from SP-API Data Kiosk Sales & Traffic (Selling Partner Insights role) — null until traffic rows exist for the ASIN. summary.adsCoverageFrom / summary.economicsCoverageFrom are each plane's earliest data date in scope (null = never synced) — suppress period-over-period comparisons whose PRIOR window reaches before them, or the partial prior period fabricates growth. rows[].inventory (null until FBA inventory has synced) is point-in-time, not windowed: latest snapshot per SKU aggregated to the ASIN — fulfillable/inbound quantities summed, daysOfSupply = MIN across SKUs/marketplaces (Amazon's planning estimate, most urgent), Amazon's alert/recommendedShipInQty, estStorageNextMonth (an ESTIMATE, FX-converted, never an actual charge), agedUnits181Plus, and asOf (newest snapshot date). Parent/brand rollups sum quantities and take the MIN daysOfSupply. Pass ?asin=<ASIN> for the campaign drilldown.","security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}},{"name":"from","in":"query","required":false,"description":"Start date YYYY-MM-DD (default 30 days ago)","schema":{"type":"string"}},{"name":"to","in":"query","required":false,"description":"End date YYYY-MM-DD (default today)","schema":{"type":"string"}},{"name":"mkt","in":"query","required":false,"description":"Scope to one marketplace ID","schema":{"type":"string"}},{"name":"group","in":"query","required":false,"description":"child (default, one row per ASIN) | parent (roll up by parent ASIN)","schema":{"type":"string"}},{"name":"sort","in":"query","required":false,"description":"adSpend|adSales|acos|netSales|totalSales|refunds|grossProfit|netProfit|units|tacos|netProceeds|asin; prefix - for desc (default -adSpend)","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"1-500 (default 200)","schema":{"type":"string"}},{"name":"asin","in":"query","required":false,"description":"Drilldown: when set, returns the campaigns advertising this ASIN (per-ASIN-in-campaign spend/sales/ACoS/clicks/orders/CPC) as data.rows, instead of the product list.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/negations":{"post":{"summary":"Queue negative-keyword proposals for a wasted search term","tags":["Actions"],"description":"Body: { searchTerm, from, to, marketplace?, profile?, matchType? ('exact' default | 'phrase') }. Never writes to Amazon directly: resolves every (campaign, ad group) placement where the term spent with ZERO attributed orders in the window and inserts one pending keyword_negation action per placement into the audit-log approval queue — same pipeline, executor, and audit trail as agent-proposed actions. Approval (POST /actions/{actionId}/approve) creates the ad-group-level negative on Amazon. Dedup: placements already covered by an existing negative (ad-group or campaign level) or an already-pending proposal are skipped and counted. Capped at 25 placements per request.","security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/payouts":{"get":{"summary":"Settlement summaries, newest first — the cash that actually landed","tags":["Data"],"description":"Each row is one closed settlement: settlementId, startDate, endDate, depositDate (null until Amazon stamps it), totalAmount, currency, marketplace. Amounts stay in the settlement's OWN currency — payouts are region-wide disbursements and the bank deposit is in that currency, so no FX conversion is applied. Only closed settlements exist (Amazon exposes no open-settlement running total); estimate the next close from the account's own cadence between end dates.","security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Max settlements returned (default 12, cap 50)","schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/fees":{"get":{"summary":"Fee line items — the granular breakdown behind the Profit number","tags":["Data"],"description":"Account mode adds account-level charges from the Finances-API cost ledger (subscription, storage, AGL freight/duty, removals — grains Amazon never attributes to a product; order/SKU-grain fees are excluded to avoid double-counting the per-product fees) and seller-entered indirect expenses booked in the window. Fee-plane semantics: ledger fee families are TAX-INCLUSIVE and bucketed by POSTED date; economics (Data Kiosk) fees are ORDER-date bucketed and tax-split — so family-level comparisons between the two planes are only meaningful at weekly+ granularity (day-level drift is posting lag, not a bug), and order/SKU-grain ledger fees must NEVER be added into account mode (same money as the product-attributed economics fees — double-count). Mixed-currency scopes convert to the org display currency. Payouts are settlement summaries — actual Amazon disbursements whose deposit date (or period end) falls in the window, converted from the settlement's own currency. Informational: not part of the fee waterfall (the fees above already explain where the money went), and region-wide (never scoped by mkt).","security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}},{"name":"from","in":"query","required":false,"description":"Start date YYYY-MM-DD (default 30 days ago)","schema":{"type":"string"}},{"name":"to","in":"query","required":false,"description":"End date YYYY-MM-DD (default today)","schema":{"type":"string"}},{"name":"mkt","in":"query","required":false,"description":"Scope to one marketplace ID","schema":{"type":"string"}},{"name":"asin","in":"query","required":false,"description":"Product mode: this ASIN's Amazon fee components (Data Kiosk FeeSummary), one line per fee type. Omit for account mode.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/costs":{"get":{"summary":"Product COGS rows — per-unit cost elements with effective-date periods","tags":["Data"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}},{"name":"asin","in":"query","required":false,"description":"Scope to one ASIN","schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}},"post":{"summary":"Bulk-upsert product COGS rows (the CSV-import path)","tags":["Data"],"description":"Upserts by (asin, marketplace, element, effectiveFrom) — re-importing a sheet is idempotent; a new effectiveFrom starts a new price period. COGS is date-weighted into Explore's Profit/Margin (marketplace-specific rows win over all-marketplace rows).","security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"rows":{"type":"string","description":"array of { asin, element (unit_cost|packaging|supplier_shipping|inbound_freight|other), amountPerUnit, currency, effectiveFrom, effectiveTo?, marketplace?, note? }"}}}}}},"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}},"delete":{"summary":"Delete one product COGS row","tags":["Data"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"query","required":true,"description":"Cost row id","schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/expenses":{"get":{"summary":"Indirect expenses — seller-entered costs Amazon doesn't know about","tags":["Data"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}},"post":{"summary":"Create or update (with body.id) an indirect expense","tags":["Data"],"description":"Occurrences book in full on their date (monthly bills clamp short months, e.g. Jan 31 → Feb 28). Expenses surface in /fees account mode.","security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"string (required)"},"amount":{"type":"string","description":"positive number (required)"},"currency":{"type":"string","description":"ISO code (required)"},"recurrence":{"type":"string","description":"one_time (default) | monthly | yearly"},"startDate":{"type":"string","description":"YYYY-MM-DD (required; one_time: the date, recurring: first occurrence)"},"endDate":{"type":"string","description":"YYYY-MM-DD | null (recurring: last occurrence date)"},"marketplace":{"type":"string","description":"marketplace ID | null (null = account-wide)"},"asin":{"type":"string","description":"ASIN | null"},"category":{"type":"string","description":"free-form label | null"},"countAsAdvertising":{"type":"string","description":"boolean — reclass into advertising in P&L groupings"},"id":{"type":"string","description":"expense id (update instead of create)"}}}}}},"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}},"delete":{"summary":"Delete one indirect expense","tags":["Data"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"query","required":true,"description":"Expense id","schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/campaigns":{"get":{"summary":"List synced campaigns (SP, SB, and SD)","tags":["Data"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}},{"name":"profileId","in":"query","required":false,"description":"Filter to one advertising profile","schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/campaigns/{campaignId}":{"get":{"summary":"Campaign drill-down: series, summary, top keywords","tags":["Data"],"description":"campaignId accepts the Amazon campaign ID (preferred) or internal UUID.","security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}},{"name":"campaignId","in":"path","required":true,"schema":{"type":"string"}},{"name":"days","in":"query","required":false,"description":"Lookback 1-90 (default 30)","schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/performance":{"get":{"summary":"Org-wide daily performance series + summary","tags":["Data"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}},{"name":"days","in":"query","required":false,"description":"Lookback 1-90 (default 30)","schema":{"type":"string"}},{"name":"profileId","in":"query","required":false,"description":"Filter to one advertising profile","schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/outcomes":{"get":{"summary":"Agent impact: measured 14-day pre/post action outcomes","tags":["Data"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/audit-log":{"get":{"summary":"List audit log entries (every agent decision + execution)","tags":["Data"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Max 200 (default 50)","schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/audit-log/export":{"get":{"summary":"CSV export of the full audit log","tags":["Data"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/export":{"get":{"summary":"GDPR/CCPA full data export (JSON)","tags":["Data"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/sync":{"get":{"summary":"List data sync jobs and their status","tags":["Sync"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}},"post":{"summary":"Trigger a manual sync (campaigns, performance, search terms, order metrics)","tags":["Sync"],"description":"Returns 202 with Inngest event ids; poll GET /sync for completion.","security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"profileId":{"type":"string","description":"string (preferred)"},"marketplace":{"type":"string","description":"string (legacy fallback)"},"syncTypes":{"type":"string","description":"string[] of campaigns | campaign_performance | search_terms (default all three)"},"startDate":{"type":"string","description":"YYYY-MM-DD (default 14d ago)"},"endDate":{"type":"string","description":"YYYY-MM-DD (default today)"}}}}}},"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/organizations/{orgId}/invites":{"get":{"summary":"List team invites","tags":["Organization"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}},"post":{"summary":"Invite a teammate (owner only)","tags":["Organization"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","description":"string (required)"},"orgRole":{"type":"string","description":"operator | viewer"}}}}}},"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/billing/checkout":{"post":{"summary":"Create a Stripe Checkout session","tags":["Billing"],"security":[{"bearerAuth":[]}],"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"priceId":{"type":"string","description":"Stripe price id"}}}}}},"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}},"/api/billing/portal":{"post":{"summary":"Create a Stripe customer portal session","tags":["Billing"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success"},"401":{"description":"Missing or invalid credentials"},"403":{"description":"Wrong organization"}}}}}}