Skip to main content

WeInc API / Endpoint reference

Headless build walkthrough

Build, change and publish a client's website from your own backend or AI agent, with no browser. Every call uses your organization API key: Authorization: Bearer wk_….

1. Create the client and send their invitation

A client is the business the site is for. This is the one step a person must do: the client opens the emailed invitation, signs in or signs up (verifying their email) and accepts. WeInc never creates or links an account on someone's behalf. Poll the client until status is active, then carry on headless. The activate response is the same whether or not the address already has a WeInc account.

curl -X POST https://my.we.inc/api/v1/clients -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","name":"Rosa","company":"Rosa Bakery"}'
# → { "client": { "id": "CLIENT_ID", ... } }

curl -X POST https://my.we.inc/api/v1/clients/CLIENT_ID/activate -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json"
# → { "client_id": "CLIENT_ID", "status": "invitation_sent" }   ("active" once accepted)

curl https://my.we.inc/api/v1/clients/CLIENT_ID -H "Authorization: Bearer $WEINC_KEY"
# → { "client": { "status": "active", ... } }

2. Set a monthly credit limit for the client (optional)

Once the client has used this many AI credits in the calendar month (UTC), new AI turns are refused with 402 and code client_credit_cap. Send null to remove the limit. The limit is checked before each turn starts, so one turn already running can take a client slightly over it.

curl -X PATCH https://my.we.inc/api/v1/clients/CLIENT_ID -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" -d '{"monthly_credit_cap": 2000}'

3. Create a project

Starts empty, or as a copy of one of your templates (template_id).

curl -X POST https://my.we.inc/api/v1/projects -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" \
  -d '{"client_email":"[email protected]","name":"Rosa Bakery website"}'
# → { "project": { "id": "PROJECT_ID", ... } }

4. Tell the AI what to build

This is the same AI turn the builder chat runs: same prompts, same credit charge, and the files are saved on our servers when it finishes. Use async and poll: a first build often takes 3 to 8 minutes, and a turn can run for up to about 13 minutes. Send later changes the same way; each turn continues the project's latest conversation unless you pass conversationId or newConversation.

curl -X POST https://my.we.inc/api/v1/projects/PROJECT_ID/chat -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" \
  -d '{"message":"A warm, modern site for Rosa Bakery in Lisbon: menu, opening hours, contact form, online orders.","async":true}'
# → 202 { "turnId": "api-…", "status": "running", "poll": "https://my.we.inc/api/v1/projects/PROJECT_ID/turns/api-…" }

5. Poll until the turn finishes

Poll every 5 to 10 seconds. A completed turn returns the AI's summary, the files it changed and the credits it was charged. For a small change, "wait": true holds the request for up to about 85 seconds and returns this same result, or 202 with a turnId if it needs longer.

curl https://my.we.inc/api/v1/projects/PROJECT_ID/turns/TURN_ID -H "Authorization: Bearer $WEINC_KEY"
# → { "status": "completed", "summary": "Built the home, menu and contact pages…",
#     "filesChanged": ["src/App.tsx", "src/pages/Menu.tsx"], "creditsUsed": 48,
#     "conversationId": "…" }

6. Deploy to a live URL

The site is built on our build service and published, with the same rules and history as publishing from the builder. If the site uses WeInc Cloud (database, sign-in, file storage), its backend is set up during this publish. Poll every 3 to 5 seconds; a build usually takes 30 to 120 seconds. There is no live preview without a browser, so the published URL is your preview. Deploy again after every change you want live.

curl -X POST https://my.we.inc/api/v1/projects/PROJECT_ID/deploy -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json"
# → 202 { "jobId": "JOB", "status": "building", "poll": "…/deploy?job=JOB" }

curl "https://my.we.inc/api/v1/projects/PROJECT_ID/deploy?job=JOB" -H "Authorization: Bearer $WEINC_KEY"
# → { "status": "ready", "url": "https://…" }   (or { "status": "error", "stage": "build", "error": "…" })

7. Connect a custom domain

Returns the DNS records the domain owner must add. For your clients' projects, your organization's client settings decide whether custom domains are allowed; no WeInc plan is needed. Sandbox projects cannot have domains.

curl -X POST https://my.we.inc/api/v1/projects/PROJECT_ID/domains -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" -d '{"domain":"www.rosabakery.example"}'
curl https://my.we.inc/api/v1/projects/PROJECT_ID/domains -H "Authorization: Bearer $WEINC_KEY"

# Remove it again (also clears its routing); test keys cannot add or remove domains
curl -X DELETE "https://my.we.inc/api/v1/projects/PROJECT_ID/domains?domain=www.rosabakery.example" -H "Authorization: Bearer $WEINC_KEY"

8. Load store products

Up to 200 products per call, created or updated by handle (or by variant SKU). Prices are in cents. Images must be https URLs, up to 20 per product. New products are drafts unless you send status "active". Each item gets its own result, so one bad item never fails the rest. To take payments, call POST /api/v1/projects/PROJECT_ID/store/connect and send the returned Stripe link to the merchant: completing Stripe's own form is the one manual step, and it needs no WeInc login. Discounts, shipping rates and store settings (currency, automatic tax, checkout open) have their own endpoints under /store.

curl -X POST https://my.we.inc/api/v1/projects/PROJECT_ID/products -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" -d '{"products":[
  {"title":"Pastel de nata","status":"active","images":["https://cdn.example/nata.jpg"],
   "variants":[{"title":"Single","sku":"NATA-1","price":180,"inventory_count":120},
               {"title":"Box of 6","sku":"NATA-6","price":950,"inventory_count":30}]}]}'
# → { "created": 1, "updated": 0, "failed": 0, "results": [ … ] }

# Stock changes (absolute counts, up to 500 per call)
curl -X PATCH https://my.we.inc/api/v1/projects/PROJECT_ID/products -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" \
  -d '{"inventory":[{"sku":"NATA-1","inventory_count":80}]}'

# Remove products
curl -X DELETE https://my.we.inc/api/v1/projects/PROJECT_ID/products -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" -d '{"handles":["pastel-de-nata"]}'

9. Watch credit use

Credits used per client and per project, counting only your organization's projects. Defaults to this month so far (UTC); from and to take ISO dates, up to 366 days apart.

curl "https://my.we.inc/api/v1/usage?clientId=CLIENT_ID&from=2026-10-01&to=2026-11-01" -H "Authorization: Bearer $WEINC_KEY"
# → { "totalCreditsUsed": 412, "clients": [ { "clientId": "…", "monthlyCreditCap": 2000,
#      "creditsUsed": 412, "projects": [ { "projectId": "…", "creditsUsed": 412 } ] } ] }

10. Estimate a turn before running it

A credit range from what similar turns actually cost: this project's own edits once it has five, otherwise recent turns across the platform. It is an estimate, not a quote; nothing is charged by asking.

curl -X POST https://my.we.inc/api/v1/projects/PROJECT_ID/estimate -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" -d '{"message":"Add a gallery page"}'
# → { "kind": "edit", "basis": "this_project", "low": 6, "typical": 11, "high": 24, "upfrontHold": 8, ... }

11. Edit code directly (no credits)

Read and write source files without the AI (PATCH or PUT /files; both write the named files, delete those set to null and keep the rest). Files set to null are deleted; others are untouched. The current files are saved first as a snapshot the owner can restore in the builder's history. Up to 200 files and 1 MB per file per call. Deploy afterwards to go live.

curl "https://my.we.inc/api/v1/projects/PROJECT_ID/files?path=src/App.tsx" -H "Authorization: Bearer $WEINC_KEY"
curl -X PATCH https://my.we.inc/api/v1/projects/PROJECT_ID/files -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" \
  -d '{"files":{"src/components/Banner.tsx":"export default function Banner(){return <p>Open late</p>}","src/Old.tsx":null}}'
# → { "written": ["src/components/Banner.tsx"], "deleted": ["src/Old.tsx"], "snapshotId": "api-edit-…" }

12. Read orders and customers

Storefront orders (newest first, with line items) and customers. Amounts are in cents. An unpaid (pending) order can be canceled; paid orders cannot be canceled or have money returned through the API: the store owner handles that in their own Stripe dashboard.

curl "https://my.we.inc/api/v1/projects/PROJECT_ID/store/orders?status=paid&from=2026-10-01&limit=50" -H "Authorization: Bearer $WEINC_KEY"
curl https://my.we.inc/api/v1/projects/PROJECT_ID/store/orders/ORDER_ID -H "Authorization: Bearer $WEINC_KEY"
curl https://my.we.inc/api/v1/projects/PROJECT_ID/store/customers -H "Authorization: Bearer $WEINC_KEY"
curl -X POST https://my.we.inc/api/v1/projects/PROJECT_ID/store/orders/ORDER_ID/cancel -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json"

13. Get told when things happen

Register an HTTPS endpoint. Events: store.order.created, store.order.paid, store.order.canceled, product.low_stock (stock at or below 5), deploy.succeeded, deploy.failed, turn.completed, turn.failed (plus client.created, client.updated, plan.created). Verify X-Webhook-Signature (HMAC-SHA256 of the raw body with your secret). Each event has a stable data.event_id and is sent once; de-duplicate on it. Delivery is a single attempt; use the read endpoints to reconcile.

curl -X POST https://my.we.inc/api/v1/webhooks -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" -d '{"url":"https://agent.example/weinc","events":["store.order.paid","deploy.failed","turn.completed"]}'
# → { "webhook": { "id": "…", "secret": "…" } }   (the secret is shown once)

14. Collections and storefront search

Give products collection handles in the bulk import ("collections": ["bread"]). The site's public products endpoint, GET /api/store/products, also takes q, collection, min_price, max_price (cents), in_stock, sort (newest, price_asc, price_desc, title), limit and offset. Without them it answers exactly as before.

GET /api/store/products?projectId=PROJECT_ID&signature=SIG&collection=bread&in_stock=true&sort=price_asc&limit=20

15. Export or move a project

Export returns one JSON file: source files, products, orders, customers and the site's database rows (up to 200 rows per table). Transfer moves the project, with its conversations, history, store and database, to another of your clients who has an account and isn't removed, suspended or churned; connected integrations must be reconnected. Account and credential tables are never exported.

curl https://my.we.inc/api/v1/projects/PROJECT_ID/export -H "Authorization: Bearer $WEINC_KEY" -o export.json
curl -X POST https://my.we.inc/api/v1/projects/PROJECT_ID/transfer -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" -d '{"toClientId":"OTHER_CLIENT_ID"}'

16. Roles for the site's own users

Sites with accounts (WeInc Cloud) can have roles such as staff or manager. A role gives read, insert, update or delete on named tables; on a table with role permissions, those reach every member's rows, and only roles with insert (or a site admin) may add rows. Everyone keeps their own rows. A site with no roles works exactly as before. Generated code can show staff screens with myRoles(); the server enforces the rules. A role can also carry write rules per table: columns (the only fields it may write) and values ({ field: [allowed values] }). The reserved role "member" holds rules for everyone without a role that grants the write (it grants nothing itself and cannot be assigned). A refused write gets 403.

curl -X PUT https://my.we.inc/api/v1/projects/PROJECT_ID/cloud/roles/staff -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" -d '{"tables":{"bookings":{"read":true,"update":true,"values":{"status":["pending","confirmed"]}}}}'
curl -X PUT https://my.we.inc/api/v1/projects/PROJECT_ID/cloud/roles/manager -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" -d '{"tables":{"bookings":{"read":true,"update":true}}}'
curl -X PUT https://my.we.inc/api/v1/projects/PROJECT_ID/cloud/roles/member -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" -d '{"tables":{"bookings":{"columns":["date","notes","status"],"values":{"status":["pending"]}}}}'
curl -X POST https://my.we.inc/api/v1/projects/PROJECT_ID/cloud/roles/staff/members -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" -d '{"email":"[email protected]"}'
curl https://my.we.inc/api/v1/projects/PROJECT_ID/cloud/roles -H "Authorization: Bearer $WEINC_KEY"

17. Test mode

Create a test key in the dashboard (POST /api/organizations/:id/api-keys with "test": true and an optional "monthly_credit_cap"); it starts with wk_test_. It can only act on the sandbox projects it creates. Their store checkout only runs in Stripe test mode, they publish with noindex and cannot take a custom domain, and their webhooks carry test: true. A test key can register its own webhooks (POST /api/v1/webhooks); those receive only sandbox events, and live webhooks never receive sandbox events. AI turns still cost real credits, up to the key's own monthly cap (200 by default).

curl -X POST https://my.we.inc/api/v1/projects -H "Authorization: Bearer $WEINC_TEST_KEY" -H "Content-Type: application/json" \
  -d '{"client_email":"[email protected]","name":"Sandbox: Rosa Bakery"}'

18. Discount codes

Create, list, change and delete discount codes. type is percent (value 1 to 100), fixed (value in cents) or free_shipping. Optional min_subtotal (cents), usage_limit, starts_at, ends_at and active.

curl -X POST https://my.we.inc/api/v1/projects/PROJECT_ID/store/discounts -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" -d '{"code":"TRAIL10","type":"percent","value":10,"usage_limit":100}'
curl https://my.we.inc/api/v1/projects/PROJECT_ID/store/discounts -H "Authorization: Bearer $WEINC_KEY"
curl -X PATCH https://my.we.inc/api/v1/projects/PROJECT_ID/store/discounts/DISCOUNT_ID -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" -d '{"active":false}'
curl -X DELETE https://my.we.inc/api/v1/projects/PROJECT_ID/store/discounts/DISCOUNT_ID -H "Authorization: Bearer $WEINC_KEY"

19. Shipping rates

Flat shipping rates offered at checkout for physical products, in cents. min_subtotal / max_subtotal limit a rate to a cart size (e.g. free shipping over $100); position orders them.

curl -X POST https://my.we.inc/api/v1/projects/PROJECT_ID/store/shipping-rates -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" -d '{"name":"Standard (3-5 days)","price":800,"max_subtotal":9999}'
curl -X POST https://my.we.inc/api/v1/projects/PROJECT_ID/store/shipping-rates -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" -d '{"name":"Free over $100","price":0,"min_subtotal":10000}'
curl -X PATCH https://my.we.inc/api/v1/projects/PROJECT_ID/store/shipping-rates/RATE_ID -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" -d '{"price":900}'

20. Store settings

currency (a code Stripe supports; on a store that already has products, add confirm_currency_change: true, because prices are relabelled, not converted), tax_enabled (Stripe automatic tax) and checkout_open. checkout_open and store_status set the same thing, so send one or the other in a call, never both: checkout_open true is store_status "active", false is "disabled".

curl -X PATCH https://my.we.inc/api/v1/projects/PROJECT_ID/store/settings -H "Authorization: Bearer $WEINC_KEY" -H "Content-Type: application/json" -d '{"currency":"cad","tax_enabled":true,"checkout_open":true}'
curl https://my.we.inc/api/v1/projects/PROJECT_ID/store/settings -H "Authorization: Bearer $WEINC_KEY"

Limits and what to expect

  • Webhooks: at most 10 live and 5 test endpoints per organization. Each delivery has 10 seconds in total, and only the first 4 KB of your reply is kept in the delivery log.
  • Custom domains on your clients' projects follow your client settings when your API key adds them, up to 100 custom domains across your organization's client projects. A client signed into the builder still needs a plan that includes custom domains.
  • Store currency must be one Stripe can charge in. Changing it on a store that already has products needs confirm_currency_change: true (prices are relabelled, not converted). A percent discount is at most 100.
  • Your key needs write permission for anything that changes a project. A read-only key gets 403. A key only reaches projects created under your organization (this API, your brand domain or your embed) whose owner is one of your clients who has an account and isn't removed, suspended or churned (an invited client who already has a linked account is reachable). Anything else returns 404.
  • 100 requests per minute per key, shared across the whole API. Polls count toward it.
  • One instruction may be up to 50,000 characters. A turn stops after about 13 minutes.
  • AI turns made with an API key are billed to your organization's credits, just like turns on your own brand domain. They also count against your organization's monthly cap and any per-client cap. When credits run out you get 402: insufficient_credits, org_credit_cap or client_credit_cap.
  • Turn results stay available to poll for 3 days. The files and the conversation are saved for good.
  • Checkout holds stock while a shopper pays, so the last unit cannot be sold twice. A hold lasts about 30 minutes and is given back if checkout is abandoned. One shopper can hold at most 10 of an item per order and keep at most 3 open checkouts per store.
  • Generated sites can use WeInc Cloud: a database, visitor sign-up and sign-in, rows private to each visitor by default, and private file uploads. Forms email the owner. Sites can have custom roles (step 16). Server functions are off by default.