API REFERENCEv1

Your store.
Your integrations.

Build with your products, orders, storefront, and advertising—using a consistent, store-scoped API.

BASE URLhttps://api.tecapy.com/v1/api

Interactive requests

Try the API with your credentials.

Credentials stay in this page’s memory until you clear them or leave. They are sent directly to the production API only when you run a request; they are never saved or inserted into the static examples.

No credentials loaded.

Requests go directly to https://api.tecapy.com/v1/api. The API must allow this documentation site’s origin and request headers in CORS.

Start here

Two credentials. One store.

  1. Sign in to the CRM and select your store.
  2. Open Settings → More settings → APIs & MCPs.
  3. Generate a key and save it immediately. It is displayed only once.
  4. Copy the project ID from the same page. Send both headers with every request.
cURL
export TECAPY_API_KEY="<your_api_key>"
export TECAPY_PROJECT_ID="<your_project_id>"

curl --request GET \
  --url "https://api.tecapy.com/v1/api/products?limit=20" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Keep keys on your server or in a secret manager. Do not hardcode them in browser JavaScript or place them in public code, URLs, analytics, or logs. Do not send your user ID with REST requests; it is used only by the authenticated CRM when generating a key.

Each key is bound to its project. A mismatched project ID is rejected. Generating a replacement invalidates the old key; deleting it revokes access. The CRM shows active status, never a previously generated key.

A predictable contract.

JSON over HTTPS

Send Content-Type: application/json for bodies. Successful responses contain success, message, and data; errors contain success:false, a top-level message, and error.code / error.details. IDs are opaque strings. Percent-encode path parameters; never concatenate untrusted values directly into a URL.

Partial updates

PATCH changes supplied fields only. Unknown fields are rejected. Read-only fields cannot be set, and write-only secrets are never returned.

Currency & dates

Monetary numbers are major units: 5000 means UGX 5,000. Use ISO currency/country codes. Wallet and ad settings use USD. Dates use ISO 8601 UTC; ranges are [from, to).

Pagination

Paginated collection endpoints accept limit and cursor. Use the cursor returned by the server; do not interpret it. Other arrays are complete, bounded provider reports unless noted. Default collection order is createdAt DESC, id DESC; filters and cursor stay consistent across pages.

Payments and asynchronous work

Use the Payments endpoints to create wallet, license or integration payment links. Product imports, feed refreshes and domain setup return the resource or job in a pending state; payment redirects and pending records are not proof of payment. Poll the corresponding GET endpoint for verified state. Never retry a charge blindly.

Permissions and limits

The backend must validate store access, licenses, trial eligibility, input and provider requirements for every operation. Platform admin, account signup/login, invitation acceptance, and API-key management remain authenticated CRM flows. If limited, honor Retry-After on 429; use exponential backoff for temporary 5xx errors. No fixed rate quota is promised by this draft.

Endpoint reference

Store & settings

Read and update the store bound to your key. Store creation and deletion are available only in the CRM.

GET/v1/api/storeGet store

Get store

Return the complete store data, including workingHours. Timestamps are serialized as ISO 8601 UTC strings.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/store" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "id": "your_project_id",
    "name": "Example Store",
    "slug": "example-store",
    "description": "",
    "address": "",
    "city": "Kampala",
    "contactEmail": "shop@example.com",
    "country": "Uganda",
    "countryCode": "UG",
    "createdAt": "2026-01-01T09:00:00Z",
    "currency": "UGX",
    "phoneNumber": "+256123456789",
    "state": "Central",
    "status": "live",
    "updatedAt": "2026-01-01T09:05:00Z",
    "workingHours": [
      {
        "day": "Mon-Fri",
        "isOpen": false,
        "open": "09:00",
        "close": "18:00"
      },
      {
        "day": "Sat",
        "isOpen": false,
        "open": "09:00",
        "close": "18:00"
      },
      {
        "day": "Sun",
        "isOpen": false,
        "open": "09:00",
        "close": "18:00"
      }
    ],
    "zipCode": "000",
    "googleMaps": "https://www.google.com/maps/embed?pb=<embed_parameters>"
  }
}
Try this request

Reads data from the production API.

See Store response fields ↓
PATCH/v1/api/storeUpdate store

Update store

Send only editable fields. Do not include id, slug, status, createdAt, updatedAt; these read-only fields are rejected. workingHours is an array of Mon-Fri, Sat and Sun groups with day, isOpen, open and close. A successful update returns the same full Store shape as GET.

Request fields

FieldTypeMeaning
namestringBusiness name.
descriptionstringWhat the business does.
countrystringCountry name.
countryCodestringISO 3166-1 alpha-2 country code.
currencystringStore base currency.
phoneNumberstringInternational phone number including country code.
contactEmailstringBusiness contact email.
addressstringStreet address.
citystringCity.
statestringState or region.
zipCodestringPostal code.
googleMapsstringGoogle Maps embed URL for the store location.
workingHoursarray<object>Three groups, each once: Mon-Fri, Sat, Sun. Each entry has day, isOpen, open and close. Times are local HH:mm. isOpen:false means closed. PATCH replaces the entire array.

Request

cURL
curl --request PATCH \
  --url "https://api.tecapy.com/v1/api/store" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID" \
  --header "Content-Type: application/json" \
  --data '{
  "name": "Example Store",
  "description": "Everyday home essentials.",
  "currency": "UGX",
  "googleMaps": "https://www.google.com/maps/embed?pb=<embed_parameters>",
  "workingHours": [
    {
      "day": "Mon-Fri",
      "isOpen": false,
      "open": "09:00",
      "close": "18:00"
    },
    {
      "day": "Sat",
      "isOpen": false,
      "open": "09:00",
      "close": "18:00"
    },
    {
      "day": "Sun",
      "isOpen": false,
      "open": "09:00",
      "close": "18:00"
    }
  ]
}'

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "id": "your_project_id",
    "name": "Example Store",
    "slug": "example-store",
    "description": "",
    "address": "",
    "city": "Kampala",
    "contactEmail": "shop@example.com",
    "country": "Uganda",
    "countryCode": "UG",
    "createdAt": "2026-01-01T09:00:00Z",
    "currency": "UGX",
    "phoneNumber": "+256123456789",
    "state": "Central",
    "status": "live",
    "updatedAt": "2026-01-01T09:05:00Z",
    "workingHours": [
      {
        "day": "Mon-Fri",
        "isOpen": false,
        "open": "09:00",
        "close": "18:00"
      },
      {
        "day": "Sat",
        "isOpen": false,
        "open": "09:00",
        "close": "18:00"
      },
      {
        "day": "Sun",
        "isOpen": false,
        "open": "09:00",
        "close": "18:00"
      }
    ],
    "zipCode": "000",
    "googleMaps": "https://www.google.com/maps/embed?pb=<embed_parameters>"
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

See Store response fields ↓
GET/v1/api/store/progressGet store progress

Get store progress

Read the store’s setup and activity milestones. Progress is maintained by successful store actions, not directly changed through this endpoint.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/store/progress" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "created_store": true,
    "added_products": true,
    "run_ads": true,
    "cleared_license": true,
    "custom_domain": true,
    "designed_store": true,
    "got_orders": true
  }
}
Try this request

Reads data from the production API.

Endpoint reference

Products

Maintain your inventory. Prices are in the product currency. A category and a cover image are required. image is the cover URL; images contains additional URL strings.

GET/v1/api/productsList products

List products

Cursor-paginated products. Optional categoryId and sort (newest, oldest, price-asc, price-desc, name-asc, name-desc).

Query parameters: categoryId, sort.

Pagination: limit (1–100, default 20), cursor (opaque). For the first page, omit cursor. For the next page, replace your_next_cursor in the example with meta.nextCursor, keeping the same filters and sort. Stop when meta.hasMore is false.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/products?categoryId=cat_123&sort=newest&limit=20&cursor=your_next_cursor" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": [
    {
      "id": "prod_123",
      "projectId": "your_project_id",
      "slug": "battery-charger",
      "name": "Battery Charger",
      "brand": "Example Brand",
      "category": "Mechanical equipment",
      "categoryId": "cat_123",
      "description": "A workshop charger for compatible 12V and 24V batteries.",
      "price": 900000,
      "currency": "UGX",
      "condition": "new",
      "inStock": true,
      "image": "https://example.com/charger-cover.webp",
      "images": [
        "https://example.com/charger-side.webp"
      ],
      "facebookVideo": null,
      "tiktokVideo": null,
      "youtubeVideo": null,
      "createdAt": "2026-01-01T09:00:00Z",
      "updatedAt": "2026-01-01T09:05:00Z"
    }
  ],
  "meta": {
    "nextCursor": null,
    "hasMore": false
  }
}
Try this request

Reads data from the production API.

See Product response fields ↓
POST/v1/api/productsCreate product

Create product

Send editable fields only. image is the cover URL and images is an array of additional URL strings. Do not send id, projectId, slug, createdAt or updatedAt. The backend validates image URLs and queues feed updates.

Request fields

FieldTypeMeaning
nameRequiredstringProduct title, natural capitalization, maximum 100 characters.
brandRequiredstringBrand or Unbranded.
categoryRequiredstringCategory display name.
categoryIdRequiredstringOpaque resource ID.
descriptionRequiredstringPlain-text description.
priceRequirednumberRegular price in the product currency.
discountPricenumber / nullOptional sale price, greater than zero and lower than price; null removes the discount.
currencyRequiredstringISO 4217 currency code.
conditionRequiredstringProduct condition.new · used · refurbished
inStockRequiredbooleanWhether the product is available.
imageRequiredstringCover image: one public HTTPS URL.
imagesarray<string>Additional image URLs, as strings, not objects. The cover image is separate in image; maximum six images including the cover.
facebookVideostring / nullFacebook video URL, or null.
tiktokVideostring / nullTikTok video URL, or null.
youtubeVideostring / nullYouTube video URL, or null.

Request

cURL
curl --request POST \
  --url "https://api.tecapy.com/v1/api/products" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID" \
  --header "Content-Type: application/json" \
  --data '{
  "name": "Battery Charger",
  "brand": "Example Brand",
  "category": "Mechanical equipment",
  "categoryId": "cat_123",
  "description": "A workshop charger for compatible 12V and 24V batteries.",
  "price": 900000,
  "currency": "UGX",
  "condition": "new",
  "inStock": true,
  "image": "https://example.com/charger-cover.webp",
  "images": [
    "https://example.com/charger-side.webp"
  ],
  "facebookVideo": null,
  "tiktokVideo": null,
  "youtubeVideo": null
}'

Success · 201 Created

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "id": "prod_123",
    "projectId": "your_project_id",
    "slug": "battery-charger",
    "name": "Battery Charger",
    "brand": "Example Brand",
    "category": "Mechanical equipment",
    "categoryId": "cat_123",
    "description": "A workshop charger for compatible 12V and 24V batteries.",
    "price": 900000,
    "currency": "UGX",
    "condition": "new",
    "inStock": true,
    "image": "https://example.com/charger-cover.webp",
    "images": [
      "https://example.com/charger-side.webp"
    ],
    "facebookVideo": null,
    "tiktokVideo": null,
    "youtubeVideo": null,
    "createdAt": "2026-01-01T09:00:00Z",
    "updatedAt": "2026-01-01T09:05:00Z"
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

See Product response fields ↓
GET/v1/api/products/{productId}Get product

Get product

Read a single product.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/products/your_product_id" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "id": "prod_123",
    "projectId": "your_project_id",
    "slug": "battery-charger",
    "name": "Battery Charger",
    "brand": "Example Brand",
    "category": "Mechanical equipment",
    "categoryId": "cat_123",
    "description": "A workshop charger for compatible 12V and 24V batteries.",
    "price": 900000,
    "currency": "UGX",
    "condition": "new",
    "inStock": true,
    "image": "https://example.com/charger-cover.webp",
    "images": [
      "https://example.com/charger-side.webp"
    ],
    "facebookVideo": null,
    "tiktokVideo": null,
    "youtubeVideo": null,
    "createdAt": "2026-01-01T09:00:00Z",
    "updatedAt": "2026-01-01T09:05:00Z"
  }
}
Try this request

Reads data from the production API.

See Product response fields ↓
PATCH/v1/api/products/{productId}Update product

Update product

Patch editable fields only. Do not send updatedAt, createdAt, projectId, slug or id. Keep one cover URL in image and additional URL strings in images. Send discountPrice:null to remove a sale price.

Request fields

FieldTypeMeaning
namestringProduct title, natural capitalization, maximum 100 characters.
brandstringBrand or Unbranded.
categorystringCategory display name.
categoryIdstringOpaque resource ID.
descriptionstringPlain-text description.
pricenumberRegular price in the product currency.
discountPricenumber / nullOptional sale price, greater than zero and lower than price; null removes the discount.
currencystringISO 4217 currency code.
conditionstringProduct condition.new · used · refurbished
inStockbooleanWhether the product is available.
imagestringCover image: one public HTTPS URL.
imagesarray<string>Additional image URLs, as strings, not objects. The cover image is separate in image; maximum six images including the cover.
facebookVideostring / nullFacebook video URL, or null.
tiktokVideostring / nullTikTok video URL, or null.
youtubeVideostring / nullYouTube video URL, or null.

Request

cURL
curl --request PATCH \
  --url "https://api.tecapy.com/v1/api/products/your_product_id" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID" \
  --header "Content-Type: application/json" \
  --data '{
  "price": 850000,
  "inStock": true,
  "images": [
    "https://example.com/charger-side.webp"
  ]
}'

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "id": "prod_123",
    "projectId": "your_project_id",
    "slug": "battery-charger",
    "name": "Battery Charger",
    "brand": "Example Brand",
    "category": "Mechanical equipment",
    "categoryId": "cat_123",
    "description": "A workshop charger for compatible 12V and 24V batteries.",
    "price": 900000,
    "currency": "UGX",
    "condition": "new",
    "inStock": true,
    "image": "https://example.com/charger-cover.webp",
    "images": [
      "https://example.com/charger-side.webp"
    ],
    "facebookVideo": null,
    "tiktokVideo": null,
    "youtubeVideo": null,
    "createdAt": "2026-01-01T09:00:00Z",
    "updatedAt": "2026-01-01T09:05:00Z"
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

See Product response fields ↓
DELETE/v1/api/products/{productId}Delete product

Delete product

Remove a product and its managed media; existing order snapshots remain.

Request

cURL
curl --request DELETE \
  --url "https://api.tecapy.com/v1/api/products/your_product_id" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": null
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

Endpoint reference

Categories

Organize products and choose a replacement category before deleting a category in use.

GET/v1/api/categoriesList categories

List categories

Cursor-paginated categories. sort accepts newest, oldest, name-asc or name-desc; defaults to newest.

Query parameters: sort.

Pagination: limit (1–100, default 20), cursor (opaque). For the first page, omit cursor. For the next page, replace your_next_cursor in the example with meta.nextCursor, keeping the same filters and sort. Stop when meta.hasMore is false.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/categories?sort=newest&limit=20&cursor=your_next_cursor" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": [
    {
      "id": "cat_123",
      "name": "Cleaning supplies",
      "slug": "cleaning-supplies",
      "createdAt": "2026-01-01T09:00:00Z",
      "UpdatedAt": "2026-01-01T09:05:00Z"
    }
  ],
  "meta": {
    "nextCursor": null,
    "hasMore": false
  }
}
Try this request

Reads data from the production API.

See Category response fields ↓
GET/v1/api/categories/{categoryId}Get category

Get category

Fetch one category by categoryId. Returns id, name, slug, createdAt and UpdatedAt.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/categories/your_category_id" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "id": "cat_123",
    "name": "Cleaning supplies",
    "slug": "cleaning-supplies",
    "createdAt": "2026-01-01T09:00:00Z",
    "UpdatedAt": "2026-01-01T09:05:00Z"
  }
}
Try this request

Reads data from the production API.

See Category response fields ↓
POST/v1/api/categoriesCreate category

Create category

Send name only. id, slug, createdAt and UpdatedAt are generated by the backend.

Request fields

FieldTypeMeaning
nameRequiredstringCategory name.

Request

cURL
curl --request POST \
  --url "https://api.tecapy.com/v1/api/categories" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID" \
  --header "Content-Type: application/json" \
  --data '{
  "name": "Cleaning supplies"
}'

Success · 201 Created

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "id": "cat_123",
    "name": "Cleaning supplies",
    "slug": "cleaning-supplies",
    "createdAt": "2026-01-01T09:00:00Z",
    "UpdatedAt": "2026-01-01T09:05:00Z"
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

See Category response fields ↓
PATCH/v1/api/categories/{categoryId}Rename category

Rename category

Send name only. id, slug, createdAt and UpdatedAt cannot be submitted. Returns the full category data.

Request fields

FieldTypeMeaning
nameRequiredstringCategory name.

Request

cURL
curl --request PATCH \
  --url "https://api.tecapy.com/v1/api/categories/your_category_id" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID" \
  --header "Content-Type: application/json" \
  --data '{
  "name": "Home cleaning"
}'

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "id": "cat_123",
    "name": "Cleaning supplies",
    "slug": "cleaning-supplies",
    "createdAt": "2026-01-01T09:00:00Z",
    "UpdatedAt": "2026-01-01T09:05:00Z"
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

See Category response fields ↓
DELETE/v1/api/categories/{categoryId}Delete category

Delete category

Use replacementCategoryId when products are assigned. Reject deletion without a valid replacement when required.

Query parameters: replacementCategoryId.

Request

cURL
curl --request DELETE \
  --url "https://api.tecapy.com/v1/api/categories/your_category_id?replacementCategoryId=your_replacement_category_id" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": null
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

Endpoint reference

Orders & enquiries

Read checkout orders, WhatsApp enquiries and calls. Calls/WhatsApp can contain only id, createdAt, currency, productName, total and type. Checkout orders include flat customer/address fields and item snapshots. Update an order’s fulfillment status or delete a record. Order creation remains in the storefront or CRM.

GET/v1/api/ordersList orders & enquiries

List orders & enquiries

Optional filters: type=order, type=whatsapp or type=call; from is an inclusive ISO 8601 timestamp and to is exclusive. Omit type to include all three record types. Pagination works with these filters.

Query parameters: type, from, to.

Pagination: limit (1–100, default 20), cursor (opaque). For the first page, omit cursor. For the next page, replace your_next_cursor in the example with meta.nextCursor, keeping the same filters and sort. Stop when meta.hasMore is false.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/orders?type=order&from=2026-11-01T00%3A00%3A00Z&to=2026-12-01T00%3A00%3A00Z&limit=20&cursor=your_next_cursor" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": [
    {
      "id": "order_123",
      "type": "order",
      "createdAt": "2026-01-01T09:00:00Z",
      "currency": "KES",
      "customerName": "Example Customer",
      "customerEmail": "customer@example.com",
      "apartment": "",
      "city": "Kampala",
      "country": "UG",
      "streetAddress": "Example Road",
      "postalCode": "000",
      "deliveryFee": 0,
      "fulfillment": "delivery",
      "items": [
        {
          "id": "prod_123",
          "name": "Example Product",
          "slug": "example-product",
          "currency": "KES",
          "price": 500,
          "quantity": 1
        }
      ],
      "orderStatus": "Processing",
      "paymentMethod": "dpo",
      "paymentStatus": "pending",
      "productName": "Example Product",
      "subtotal": 500,
      "total": 500
    }
  ],
  "meta": {
    "nextCursor": null,
    "hasMore": false
  }
}

Call record example

JSON
{
  "success": true,
  "message": "Success",
  "data": [
    {
      "id": "call_123",
      "createdAt": "2026-01-01T09:00:00Z",
      "currency": "KES",
      "productName": "Store enquiry",
      "total": 0,
      "type": "call"
    }
  ],
  "meta": {
    "nextCursor": null,
    "hasMore": false
  }
}

WhatsApp record example

JSON
{
  "success": true,
  "message": "Success",
  "data": [
    {
      "id": "whatsapp_123",
      "createdAt": "2026-01-01T09:00:00Z",
      "currency": "KES",
      "productName": "Store enquiry",
      "total": 0,
      "type": "whatsapp"
    }
  ],
  "meta": {
    "nextCursor": null,
    "hasMore": false
  }
}
Try this request

Reads data from the production API.

See Order response fields ↓
GET/v1/api/orders/{orderId}Get order or enquiry

Get order or enquiry

Read one record. The returned fields depend on whether its type is order, call or whatsapp.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/orders/your_order_id" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "id": "order_123",
    "type": "order",
    "createdAt": "2026-01-01T09:00:00Z",
    "currency": "KES",
    "customerName": "Example Customer",
    "customerEmail": "customer@example.com",
    "apartment": "",
    "city": "Kampala",
    "country": "UG",
    "streetAddress": "Example Road",
    "postalCode": "000",
    "deliveryFee": 0,
    "fulfillment": "delivery",
    "items": [
      {
        "id": "prod_123",
        "name": "Example Product",
        "slug": "example-product",
        "currency": "KES",
        "price": 500,
        "quantity": 1
      }
    ],
    "orderStatus": "Processing",
    "paymentMethod": "dpo",
    "paymentStatus": "pending",
    "productName": "Example Product",
    "subtotal": 500,
    "total": 500
  }
}
Try this request

Reads data from the production API.

See Order response fields ↓
PATCH/v1/api/orders/{orderId}Update order status

Update order status

Send orderStatus only: Processing, Shipped, Delivered or Cancelled. Other fields cannot be updated through this endpoint. Returns the updated order.

Request fields

FieldTypeMeaning
orderStatusRequiredstringCheckout fulfillment status.Processing · Shipped · Delivered · Cancelled

Request

cURL
curl --request PATCH \
  --url "https://api.tecapy.com/v1/api/orders/your_order_id" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID" \
  --header "Content-Type: application/json" \
  --data '{
  "orderStatus": "Shipped"
}'

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "id": "order_123",
    "type": "order",
    "createdAt": "2026-01-01T09:00:00Z",
    "currency": "KES",
    "customerName": "Example Customer",
    "customerEmail": "customer@example.com",
    "apartment": "",
    "city": "Kampala",
    "country": "UG",
    "streetAddress": "Example Road",
    "postalCode": "000",
    "deliveryFee": 0,
    "fulfillment": "delivery",
    "items": [
      {
        "id": "prod_123",
        "name": "Example Product",
        "slug": "example-product",
        "currency": "KES",
        "price": 500,
        "quantity": 1
      }
    ],
    "orderStatus": "Processing",
    "paymentMethod": "dpo",
    "paymentStatus": "pending",
    "productName": "Example Product",
    "subtotal": 500,
    "total": 500
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

See Order response fields ↓
DELETE/v1/api/orders/{orderId}Delete order

Delete order

Delete the order or enquiry record from this store. This permanently removes the record and does not refund payments.

Request

cURL
curl --request DELETE \
  --url "https://api.tecapy.com/v1/api/orders/your_order_id" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": null
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

Endpoint reference

Store design

Use these two endpoints for design, branding, media, checkout preferences and store policies. Policies and checkout are nested in the design record, not separate API resources.

GET/v1/api/designGet store design

Get store design

Read the store design with asset objects, checkout, policies, theme, social links and product presentation. Asset entries use id, path, type and url. All design fields are optional and allow null. fit/imageFit accepts cover or contain; productMedia accepts grid or slideshow; hero.mode accepts single, none or slideshow. feedAccess, tagManager, googleSiteVerification, updatedAt and asset path fields are read-only. Timestamps are ISO 8601 strings.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/design" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "checkout": {
      "countryDeliveryFees": {
        "US": 50000
      },
      "currency": "UGX",
      "deliveryEnabled": true,
      "deliveryFee": 5000,
      "enabled": true,
      "methods": [
        "cash-on-delivery",
        "pesapal",
        "flutterwave",
        "stripe",
        "dpo",
        "paystack",
        "paypal"
      ],
      "phoneRequired": true,
      "pickupEnabled": true,
      "whatsappEnabled": true
    },
    "designComplete": true,
    "footerLogo": {
      "id": "footer_logo",
      "path": "branding/your_project_id/footer-logo.webp",
      "type": "image/webp",
      "url": "https://example.com/footer-logo.webp"
    },
    "hero": {
      "desktop": [
        {
          "id": "hero_desktop",
          "path": "branding/your_project_id/hero-desktop.webp",
          "type": "image/webp",
          "url": "https://example.com/hero-desktop.webp"
        }
      ],
      "mobile": [
        {
          "id": "hero_mobile",
          "path": "branding/your_project_id/hero-mobile.webp",
          "type": "image/webp",
          "url": "https://example.com/hero-mobile.webp"
        }
      ],
      "fit": "cover",
      "height": 600,
      "mobileHeight": 400,
      "mode": "single",
      "videos": {
        "desktop": null,
        "mobile": null
      }
    },
    "logo": {
      "id": "logo",
      "path": "branding/your_project_id/logo.webp",
      "type": "image/webp",
      "url": "https://example.com/logo.webp"
    },
    "logoVisibility": {
      "footer": true,
      "toolbar": true
    },
    "paymentIcons": [
      {
        "id": "payment-one",
        "path": "branding/your_project_id/payment-one.webp",
        "type": "image/webp",
        "url": "https://example.com/payment-one.webp"
      },
      {
        "id": "payment-two",
        "path": "branding/your_project_id/payment-two.webp",
        "type": "image/webp",
        "url": "https://example.com/payment-two.webp"
      },
      {
        "id": "payment-three",
        "path": "branding/your_project_id/payment-three.webp",
        "type": "image/webp",
        "url": "https://example.com/payment-three.webp"
      }
    ],
    "policies": {
      "about": {
        "body": "We provide products for our local community.",
        "published": true,
        "updatedAt": "2026-01-01T09:00:00Z"
      },
      "payments": {
        "body": "Choose an available payment method at checkout.",
        "published": true,
        "updatedAt": "2026-01-01T09:00:00Z"
      },
      "privacy": {
        "body": "We use customer details to fulfill orders.",
        "published": true,
        "updatedAt": "2026-01-01T09:00:00Z"
      },
      "returns": {
        "body": "Contact us about eligible returns.",
        "published": true,
        "updatedAt": "2026-01-01T09:00:00Z"
      },
      "shipping": {
        "body": "Contact us for delivery availability.",
        "published": true,
        "updatedAt": "2026-01-01T09:00:00Z"
      },
      "terms": {
        "body": "Please review our store terms before ordering.",
        "published": true,
        "updatedAt": "2026-01-01T09:00:00Z"
      },
      "faq": {
        "body": "Contact us if you have questions about products or delivery.",
        "published": true,
        "updatedAt": "2026-01-01T09:00:00Z"
      }
    },
    "productCard": {
      "border": true,
      "buttons": true,
      "imageFit": "cover",
      "imageHeight": 280,
      "mobileImageHeight": 180
    },
    "productMedia": "slideshow",
    "schemaVersion": 1,
    "socialLinks": {
      "facebook": "https://facebook.com/example",
      "instagram": "https://instagram.com/example",
      "linkedin": "https://linkedin.com/example",
      "pinterest": "https://pinterest.com/example",
      "tiktok": "https://tiktok.com/example",
      "x": "https://x.com/example",
      "youtube": "https://youtube.com/example"
    },
    "theme": {
      "background": "#ffffff",
      "primary": "#171080",
      "secondary": "#111827"
    },
    "toolbarLogo": {
      "id": "toolbar_logo",
      "path": "branding/your_project_id/toolbar-logo.webp",
      "type": "image/webp",
      "url": "https://example.com/toolbar-logo.webp"
    },
    "updatedAt": "2026-01-01T09:00:00Z",
    "tagManager": "GTM-XXXXXXX",
    "googleSiteVerification": "<google_site_verification_token>",
    "crawlersEnabled": false,
    "currencySettings": {
      "baseCurrency": "UGX",
      "rates": {
        "USD": 0.00024
      }
    },
    "feedAccess": {
      "hash": "<server_generated_feed_hash>",
      "version": 1
    }
  }
}
Try this request

Reads data from the production API.

See Design response fields ↓
PATCH/v1/api/designUpdate store design

Update store design

Patch the design fields you want to change. Include checkout preferences under checkout and pages under policies.<page>. Media fields use asset objects; toolbarLogo/footerLogo and video slots may be null. No design field is required; null is allowed. Do not send server-controlled feedAccess, tagManager, googleSiteVerification, updatedAt, schemaVersion or path inside media objects. The request example includes every editable field; the response returns the full design, including read-only fields.

Request fields

FieldTypeMeaning
checkoutobject / nullSee the OpenAPI schema for nested properties.
designCompleteboolean / nullWhether a design has been saved.
logoobject / null / nullMedia asset object, or null to clear it.
toolbarLogoobject / null / nullMedia asset object, or null to clear it.
footerLogoobject / null / nullMedia asset object, or null to clear it.
logoVisibilityobject / nullSee the OpenAPI schema for nested properties.
heroobject / nullSee the OpenAPI schema for nested properties.
paymentIconsarray / nullSee the OpenAPI schema for nested properties.
policiesobject / nullStore pages keyed by about, faq, payments, privacy, returns, shipping or terms. Save body and published under the page key.
productCardobject / nullSee the OpenAPI schema for nested properties.
productMediastring / nullProduct details layout.grid · slideshow ·
socialLinksobject / nullSocial platform names mapped to public profile URLs.
themeobject / nullSee the OpenAPI schema for nested properties.
crawlersEnabledboolean / nullAllow search engines to crawl the dedicated store domain.
currencySettingsobject / nullSee the OpenAPI schema for nested properties.

Request

cURL
curl --request PATCH \
  --url "https://api.tecapy.com/v1/api/design" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID" \
  --header "Content-Type: application/json" \
  --data '{
  "checkout": {
    "countryDeliveryFees": {
      "US": 50000
    },
    "currency": "UGX",
    "deliveryEnabled": true,
    "deliveryFee": 5000,
    "enabled": true,
    "methods": [
      "cash-on-delivery",
      "pesapal",
      "flutterwave",
      "stripe",
      "dpo",
      "paystack",
      "paypal"
    ],
    "phoneRequired": true,
    "pickupEnabled": true,
    "whatsappEnabled": true
  },
  "designComplete": true,
  "footerLogo": {
    "id": "footer_logo",
    "type": "image/webp",
    "url": "https://example.com/footer-logo.webp"
  },
  "hero": {
    "desktop": [
      {
        "id": "hero_desktop",
        "type": "image/webp",
        "url": "https://example.com/hero-desktop.webp"
      }
    ],
    "mobile": [
      {
        "id": "hero_mobile",
        "type": "image/webp",
        "url": "https://example.com/hero-mobile.webp"
      }
    ],
    "fit": "cover",
    "height": 600,
    "mobileHeight": 400,
    "mode": "single",
    "videos": {
      "desktop": null,
      "mobile": null
    }
  },
  "logo": {
    "id": "logo",
    "type": "image/webp",
    "url": "https://example.com/logo.webp"
  },
  "logoVisibility": {
    "footer": true,
    "toolbar": true
  },
  "paymentIcons": [
    {
      "id": "payment-one",
      "type": "image/webp",
      "url": "https://example.com/payment-one.webp"
    },
    {
      "id": "payment-two",
      "type": "image/webp",
      "url": "https://example.com/payment-two.webp"
    },
    {
      "id": "payment-three",
      "type": "image/webp",
      "url": "https://example.com/payment-three.webp"
    }
  ],
  "policies": {
    "about": {
      "body": "We provide products for our local community.",
      "published": true
    },
    "payments": {
      "body": "Choose an available payment method at checkout.",
      "published": true
    },
    "privacy": {
      "body": "We use customer details to fulfill orders.",
      "published": true
    },
    "returns": {
      "body": "Contact us about eligible returns.",
      "published": true
    },
    "shipping": {
      "body": "Contact us for delivery availability.",
      "published": true
    },
    "terms": {
      "body": "Please review our store terms before ordering.",
      "published": true
    },
    "faq": {
      "body": "Contact us if you have questions about products or delivery.",
      "published": true
    }
  },
  "productCard": {
    "border": true,
    "buttons": true,
    "imageFit": "cover",
    "imageHeight": 280,
    "mobileImageHeight": 180
  },
  "productMedia": "slideshow",
  "socialLinks": {
    "facebook": "https://facebook.com/example",
    "instagram": "https://instagram.com/example",
    "linkedin": "https://linkedin.com/example",
    "pinterest": "https://pinterest.com/example",
    "tiktok": "https://tiktok.com/example",
    "x": "https://x.com/example",
    "youtube": "https://youtube.com/example"
  },
  "theme": {
    "background": "#ffffff",
    "primary": "#171080",
    "secondary": "#111827"
  },
  "toolbarLogo": {
    "id": "toolbar_logo",
    "type": "image/webp",
    "url": "https://example.com/toolbar-logo.webp"
  },
  "crawlersEnabled": false,
  "currencySettings": {
    "baseCurrency": "UGX",
    "rates": {
      "USD": 0.00024
    }
  }
}'

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "checkout": {
      "countryDeliveryFees": {
        "US": 50000
      },
      "currency": "UGX",
      "deliveryEnabled": true,
      "deliveryFee": 5000,
      "enabled": true,
      "methods": [
        "cash-on-delivery",
        "pesapal",
        "flutterwave",
        "stripe",
        "dpo",
        "paystack",
        "paypal"
      ],
      "phoneRequired": true,
      "pickupEnabled": true,
      "whatsappEnabled": true
    },
    "designComplete": true,
    "footerLogo": {
      "id": "footer_logo",
      "path": "branding/your_project_id/footer-logo.webp",
      "type": "image/webp",
      "url": "https://example.com/footer-logo.webp"
    },
    "hero": {
      "desktop": [
        {
          "id": "hero_desktop",
          "path": "branding/your_project_id/hero-desktop.webp",
          "type": "image/webp",
          "url": "https://example.com/hero-desktop.webp"
        }
      ],
      "mobile": [
        {
          "id": "hero_mobile",
          "path": "branding/your_project_id/hero-mobile.webp",
          "type": "image/webp",
          "url": "https://example.com/hero-mobile.webp"
        }
      ],
      "fit": "cover",
      "height": 600,
      "mobileHeight": 400,
      "mode": "single",
      "videos": {
        "desktop": null,
        "mobile": null
      }
    },
    "logo": {
      "id": "logo",
      "path": "branding/your_project_id/logo.webp",
      "type": "image/webp",
      "url": "https://example.com/logo.webp"
    },
    "logoVisibility": {
      "footer": true,
      "toolbar": true
    },
    "paymentIcons": [
      {
        "id": "payment-one",
        "path": "branding/your_project_id/payment-one.webp",
        "type": "image/webp",
        "url": "https://example.com/payment-one.webp"
      },
      {
        "id": "payment-two",
        "path": "branding/your_project_id/payment-two.webp",
        "type": "image/webp",
        "url": "https://example.com/payment-two.webp"
      },
      {
        "id": "payment-three",
        "path": "branding/your_project_id/payment-three.webp",
        "type": "image/webp",
        "url": "https://example.com/payment-three.webp"
      }
    ],
    "policies": {
      "about": {
        "body": "We provide products for our local community.",
        "published": true,
        "updatedAt": "2026-01-01T09:00:00Z"
      },
      "payments": {
        "body": "Choose an available payment method at checkout.",
        "published": true,
        "updatedAt": "2026-01-01T09:00:00Z"
      },
      "privacy": {
        "body": "We use customer details to fulfill orders.",
        "published": true,
        "updatedAt": "2026-01-01T09:00:00Z"
      },
      "returns": {
        "body": "Contact us about eligible returns.",
        "published": true,
        "updatedAt": "2026-01-01T09:00:00Z"
      },
      "shipping": {
        "body": "Contact us for delivery availability.",
        "published": true,
        "updatedAt": "2026-01-01T09:00:00Z"
      },
      "terms": {
        "body": "Please review our store terms before ordering.",
        "published": true,
        "updatedAt": "2026-01-01T09:00:00Z"
      },
      "faq": {
        "body": "Contact us if you have questions about products or delivery.",
        "published": true,
        "updatedAt": "2026-01-01T09:00:00Z"
      }
    },
    "productCard": {
      "border": true,
      "buttons": true,
      "imageFit": "cover",
      "imageHeight": 280,
      "mobileImageHeight": 180
    },
    "productMedia": "slideshow",
    "schemaVersion": 1,
    "socialLinks": {
      "facebook": "https://facebook.com/example",
      "instagram": "https://instagram.com/example",
      "linkedin": "https://linkedin.com/example",
      "pinterest": "https://pinterest.com/example",
      "tiktok": "https://tiktok.com/example",
      "x": "https://x.com/example",
      "youtube": "https://youtube.com/example"
    },
    "theme": {
      "background": "#ffffff",
      "primary": "#171080",
      "secondary": "#111827"
    },
    "toolbarLogo": {
      "id": "toolbar_logo",
      "path": "branding/your_project_id/toolbar-logo.webp",
      "type": "image/webp",
      "url": "https://example.com/toolbar-logo.webp"
    },
    "updatedAt": "2026-01-01T09:00:00Z",
    "tagManager": "GTM-XXXXXXX",
    "googleSiteVerification": "<google_site_verification_token>",
    "crawlersEnabled": false,
    "currencySettings": {
      "baseCurrency": "UGX",
      "rates": {
        "USD": 0.00024
      }
    },
    "feedAccess": {
      "hash": "<server_generated_feed_hash>",
      "version": 1
    }
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

See Design response fields ↓

Endpoint reference

Payment connections

Manage payment provider connections. Checkout preferences and payment icons belong to the store design record.

GET/v1/api/payment-gatewaysList gateway connections

List gateway connections

Return provider and connection status only, never saved secrets.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/payment-gateways" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": [
    {
      "provider": "paypal",
      "isActive": true
    }
  ]
}
Try this request

Reads data from the production API.

GET/v1/api/payment-gateways/{provider}Get payment connection

Get payment connection

Return provider and isActive for one payment provider. Saved credentials are never returned.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/payment-gateways/your_provider" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "provider": "paypal",
    "isActive": true
  }
}
Try this request

Reads data from the production API.

PUT/v1/api/payment-gateways/{provider}Connect payment gateway

Connect payment gateway

Set provider credentials. PayPal uses client_id and client_secret; provider must be flutterwave, paystack, pesapal, stripe, dpo or paypal. Stripe uses publishable_key/secret_key; DPO uses company_token/service_type; Flutterwave/Paystack use public_key/secret_key; Pesapal uses consumer_key/consumer_secret.

Request fields

FieldTypeMeaning
providerstringGateway identifier.flutterwave · paystack · pesapal · stripe · dpo · paypal
isActivebooleanConnection status.
credentialsRequiredobjectWrite onlyProvider-specific secret fields. PayPal uses client_id and client_secret. Never returned by GET.

Request

cURL
curl --request PUT \
  --url "https://api.tecapy.com/v1/api/payment-gateways/your_provider" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID" \
  --header "Content-Type: application/json" \
  --data '{
  "credentials": {
    "client_id": "your_paypal_client_id",
    "client_secret": "your_paypal_secret"
  }
}'

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "provider": "paypal",
    "isActive": true,
    "webhook": "<webhook_url>"
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

DELETE/v1/api/payment-gateways/{provider}Disconnect gateway

Disconnect gateway

Revoke or remove the provider connection.

Request

cURL
curl --request DELETE \
  --url "https://api.tecapy.com/v1/api/payment-gateways/your_provider" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": null
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

Endpoint reference

Domains & DNS

Connect existing domains, search and purchase new ones, inspect registration details, renew and manage DNS. Payment confirmation is verified server-side.

GET/v1/api/domainsList connected domains

List connected domains

Read connected hostnames.

Pagination: limit (1–100, default 20), cursor (opaque). For the first page, omit cursor. For the next page, replace your_next_cursor in the example with meta.nextCursor, keeping the same filters and sort. Stop when meta.hasMore is false.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/domains?limit=20&cursor=your_next_cursor" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": [
    {
      "hostname": "example.com"
    }
  ],
  "meta": {
    "nextCursor": null,
    "hasMore": false
  }
}
Try this request

Reads data from the production API.

POST/v1/api/domainsConnect existing domain

Connect existing domain

Start setup for a hostname. Backend includes the store slug when calling domain_management.

Request fields

FieldTypeMeaning
hostnameRequiredstringRequired. See the downloadable contract and request example.

Request

cURL
curl --request POST \
  --url "https://api.tecapy.com/v1/api/domains" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID" \
  --header "Content-Type: application/json" \
  --data '{
  "hostname": "example-store.com"
}'

Success · 201 Created

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "hostname": "example-store.com",
    "status": "pending"
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

POST/v1/api/domains/{hostname}/checkCheck domain setup

Check domain setup

Return DNS configuration actions. ADD means create the DNS record; DELETE means remove it. Each record includes action, type, name and value.

Request

cURL
curl --request POST \
  --url "https://api.tecapy.com/v1/api/domains/example-store.com/check" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 201 Created

JSON
{
  "success": true,
  "message": "Success",
  "data": [
    {
      "action": "ADD",
      "type": "CNAME",
      "name": "www",
      "value": "target.example.com"
    },
    {
      "action": "DELETE",
      "type": "CNAME",
      "name": "www",
      "value": "old-target.example.com"
    }
  ]
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

DELETE/v1/api/domains/{hostname}Remove connected domain

Remove connected domain

Disconnect this hostname; does not cancel its registration.

Request

cURL
curl --request DELETE \
  --url "https://api.tecapy.com/v1/api/domains/example-store.com" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": null
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

GET/v1/api/custom-domainsList purchased domains

List purchased domains

Read purchased domain registration and owner details. ACT means active; PEN means pending because payment has not been completed. expirationDate is Unix seconds; addressNumber is an integer. authCode is confidential.

Pagination: limit (1–100, default 20), cursor (opaque). For the first page, omit cursor. For the next page, replace your_next_cursor in the example with meta.nextCursor, keeping the same filters and sort. Stop when meta.hasMore is false.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/custom-domains?limit=20&cursor=your_next_cursor" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": [
    {
      "address": "Example Trade Center, Shop 204",
      "addressNumber": 204,
      "authCode": "<domain_auth_code>",
      "city": "Kampala",
      "contactHandle": "<contact_handle>",
      "country": "UG",
      "domainId": 12345678,
      "domainName": "example.com",
      "eMail": "owner@example.com",
      "expirationDate": 1825502994,
      "firstName": "Alex",
      "lastName": "Example",
      "phone": "456789",
      "phoneAreaCode": "123",
      "phoneCountryCode": "+256",
      "postalCode": "1101",
      "state": "Central",
      "status": "ACT"
    }
  ],
  "meta": {
    "nextCursor": null,
    "hasMore": false
  }
}
Try this request

Reads data from the production API.

See CustomDomain response fields ↓
POST/v1/api/custom-domains/registerRegister/purchase domain

Register/purchase domain

Register and purchase a domain using flat owner contact fields and domainName. state is required. Do not send status, expirationDate, domainId, contactHandle or authCode. No quoteId is needed. Follow paymentLink to complete payment.

Request fields

FieldTypeMeaning
firstNameRequiredstringRegistrant first name.
lastNameRequiredstringRegistrant surname.
eMailRequiredstringRegistrant email.
phoneCountryCodeRequiredstringCountry calling code.
phoneAreaCodeRequiredstringFirst three digits of national phone number.
phoneRequiredstringRemaining national phone number.
countryRequiredstringCountry code.
addressRequiredstringStreet name.
addressNumberRequiredintegerBuilding or address number.
cityRequiredstringCity.
stateRequiredstringRegion.
postalCodeRequiredstringPostal code.
domainNameRequiredstringPurchased domain hostname.

Request

cURL
curl --request POST \
  --url "https://api.tecapy.com/v1/api/custom-domains/register" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID" \
  --header "Content-Type: application/json" \
  --data '{
  "address": "Example Trade Center, Shop 204",
  "addressNumber": 204,
  "city": "Kampala",
  "country": "UG",
  "domainName": "example.com",
  "eMail": "owner@example.com",
  "firstName": "Alex",
  "lastName": "Example",
  "phone": "456789",
  "phoneAreaCode": "123",
  "phoneCountryCode": "+256",
  "postalCode": "1101",
  "state": "Central"
}'

Success · 201 Created

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "domain": "example.com",
    "periodYears": 1,
    "price": 0,
    "currency": "USD",
    "paymentLink": "<payment_link>",
    "payment_id": "<payment_id>"
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

GET/v1/api/custom-domains/{hostname}Get registration details

Get registration details

Return purchased domain registration and contact details. expirationDate is Unix seconds.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/custom-domains/example-store.com" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "address": "Example Trade Center, Shop 204",
    "addressNumber": 204,
    "authCode": "<domain_auth_code>",
    "city": "Kampala",
    "contactHandle": "<contact_handle>",
    "country": "UG",
    "domainId": 12345678,
    "domainName": "example.com",
    "eMail": "owner@example.com",
    "expirationDate": 1825502994,
    "firstName": "Alex",
    "lastName": "Example",
    "phone": "456789",
    "phoneAreaCode": "123",
    "phoneCountryCode": "+256",
    "postalCode": "1101",
    "state": "Central",
    "status": "ACT"
  }
}
Try this request

Reads data from the production API.

See CustomDomain response fields ↓
DELETE/v1/api/custom-domains/{hostname}Delete incomplete registration

Delete incomplete registration

Delete the saved draft only if status is not ACT. Reject active registrations.

Request

cURL
curl --request DELETE \
  --url "https://api.tecapy.com/v1/api/custom-domains/example-store.com" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": null
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

POST/v1/api/custom-domains/{hostname}/renewalRenew domain

Renew domain

Prepare a one-year renewal and return its price and payment link. Follow paymentLink to pay; the link is not proof of payment.

Request

cURL
curl --request POST \
  --url "https://api.tecapy.com/v1/api/custom-domains/example-store.com/renewal" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 201 Created

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "domain": "example.com",
    "periodYears": 1,
    "price": 0,
    "currency": "USD",
    "paymentLink": "<payment_link>",
    "payment_id": "<payment_id>"
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

POST/v1/api/custom-domains/{hostname}/connectConnect purchased domain

Connect purchased domain

Configure the purchased domain for this store.

Request

cURL
curl --request POST \
  --url "https://api.tecapy.com/v1/api/custom-domains/example-store.com/connect" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 201 Created

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "hostname": "example-store.com",
    "status": "pending"
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

GET/v1/api/custom-domains/{hostname}/dnsList DNS records

List DNS records

Read DNS records.

Pagination: limit (1–100, default 20), cursor (opaque). For the first page, omit cursor. For the next page, replace your_next_cursor in the example with meta.nextCursor, keeping the same filters and sort. Stop when meta.hasMore is false.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/custom-domains/example-store.com/dns?limit=20&cursor=your_next_cursor" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": [
    {
      "id": "dns_123",
      "name": "www",
      "type": "CNAME",
      "value": "example-store.com",
      "ttl": 3600
    }
  ],
  "meta": {
    "nextCursor": null,
    "hasMore": false
  }
}
Try this request

Reads data from the production API.

See DnsRecord response fields ↓
POST/v1/api/custom-domains/{hostname}/dnsAdd DNS record

Add DNS record

Validate record type, target and TTL.

Request fields

FieldTypeMeaning
nameRequiredstringRecord host/name.
typeRequiredstringRecord type.A · AAAA · CNAME · MX · TXT · NS · SOA · CAA · SRV
valueRequiredstringRecord target/value.
ttlRequiredintegerSee the OpenAPI schema for nested properties.
priorityintegerSee the OpenAPI schema for nested properties.

Request

cURL
curl --request POST \
  --url "https://api.tecapy.com/v1/api/custom-domains/example-store.com/dns" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID" \
  --header "Content-Type: application/json" \
  --data '{
  "name": "www",
  "type": "CNAME",
  "value": "example-store.com",
  "ttl": 3600
}'

Success · 201 Created

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "id": "dns_123",
    "name": "www",
    "type": "CNAME",
    "value": "example-store.com",
    "ttl": 3600
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

See DnsRecord response fields ↓
DELETE/v1/api/custom-domains/{hostname}/dns/{recordId}Delete DNS record

Delete DNS record

Openprovider NS and SOA records are protected and must be rejected.

Request

cURL
curl --request DELETE \
  --url "https://api.tecapy.com/v1/api/custom-domains/example-store.com/dns/your_record_id" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": null
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

Endpoint reference

Advertising & tracking

Independent integrations use OAuth consent. Managed Google campaigns share the same wallet and setup checks as the CRM. Advertising-platform credentials never appear in responses.

GET/v1/api/advertising/integrationsGet ad connections

Get ad connections

Connection status for google, meta, tiktok, x, reddit, pinterest, snapchat, bing and google_tag. mode is managed or independent. Google Tag Manager uses google_tag under Independent integrations.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/advertising/integrations" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": [
    {
      "platform": "google",
      "mode": "managed",
      "isActive": true
    },
    {
      "platform": "google_tag",
      "mode": "independent",
      "isActive": true
    }
  ]
}
Try this request

Reads data from the production API.

See AdIntegration response fields ↓
POST/v1/api/advertising/integrations/{platform}/authorizationBegin Independent authorization

Begin Independent authorization

Return a short-lived authorization URL. The account holder completes consent in the browser. Use platform google_tag for Google Tag Manager, like other Independent integrations.

Request fields

FieldTypeMeaning
returnUrlRequiredstringRequired. See the downloadable contract and request example.

Request

cURL
curl --request POST \
  --url "https://api.tecapy.com/v1/api/advertising/integrations/your_platform/authorization" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID" \
  --header "Content-Type: application/json" \
  --data '{
  "returnUrl": "https://example-store.com/integration-return"
}'

Success · 201 Created

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "authorizationUrl": "https://example.com/oauth/authorize",
    "expiresAt": "2026-11-09T12:15:00Z"
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

DELETE/v1/api/advertising/integrations/{platform}Disconnect integration

Disconnect integration

Disconnect the platform and revoke saved access where supported.

Request

cURL
curl --request DELETE \
  --url "https://api.tecapy.com/v1/api/advertising/integrations/your_platform" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": null
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

POST/v1/api/feeds/credentialsGenerate feed credentials

Generate feed credentials

Generate/replace catalog access credentials. Credentials are sensitive and must use no-store responses.

Request

cURL
curl --request POST \
  --url "https://api.tecapy.com/v1/api/feeds/credentials" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 201 Created

JSON
{
  "success": true,
  "message": "Success",
  "data": [
    {
      "platform": "google",
      "url": "https://example-store.com/feed/google.xml",
      "username": "<feed_username>",
      "password": "<feed_password>"
    }
  ]
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

GET/v1/api/feedsGet catalog feed

Get catalog feed

Read catalog feed URLs and access credentials for supported platforms. Treat these credentials as confidential. Feed format and availability/condition casing depend on platform.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/feeds" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": [
    {
      "platform": "google",
      "url": "https://example-store.com/feed/google.xml",
      "username": "<feed_username>",
      "password": "<feed_password>"
    }
  ]
}
Try this request

Reads data from the production API.

POST/v1/api/feeds/refreshRefresh Google product feed

Refresh Google product feed

Invoke google_feed with projectId only. Return an accepted refresh job.

Request

cURL
curl --request POST \
  --url "https://api.tecapy.com/v1/api/feeds/refresh" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 201 Created

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "jobId": "job_123",
    "status": "queued"
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

GET/v1/api/advertising/campaignGet managed campaign

Get managed campaign

Return campaign and advertiser identifiers plus settings.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/advertising/campaign" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "campaignId": "campaign_123",
    "advertiserId": "advertiser_123",
    "merchantId": "merchant_123",
    "platform": "google",
    "status": "active",
    "budget": 1,
    "maxCpc": 0.1,
    "countryCode": "UG",
    "country": "Uganda",
    "schedule": {
      "monday": {
        "start_hour": 6,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 30
      },
      "tuesday": {
        "start_hour": 6,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 30
      },
      "wednesday": {
        "start_hour": 6,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 30
      },
      "thursday": {
        "start_hour": 6,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 30
      },
      "friday": {
        "start_hour": 6,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 30
      },
      "saturday": {
        "start_hour": 6,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 30
      },
      "sunday": {
        "start_hour": 6,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 30
      }
    }
  }
}
Try this request

Reads data from the production API.

See Campaign response fields ↓
POST/v1/api/advertising/campaignProvision managed campaign

Provision managed campaign

Google only. Validate license, store merchant details and verified wallet funds. Merchant details are resolved from this store, not trusted from another project.

Request fields

FieldTypeMeaning
platformRequiredstringManaged provider.google
statusRequiredstringRequested campaign state.active · inactive
budgetRequirednumberAverage daily budget in USD.
maxCpcRequirednumberMaximum USD cost per click.
countryCodeRequiredstringTarget country code.
countryRequiredstringTarget country name.
scheduleRequiredobjectAll seven day names required; start must precede end.
timeZonestringIANA timezone. Accepted only when creating a campaign; cannot be updated. Omit if unknown.

Request

cURL
curl --request POST \
  --url "https://api.tecapy.com/v1/api/advertising/campaign" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID" \
  --header "Content-Type: application/json" \
  --data '{
  "platform": "google",
  "status": "active",
  "budget": 1,
  "maxCpc": 0.1,
  "countryCode": "UG",
  "country": "Uganda",
  "schedule": {
    "monday": {
      "start_hour": 6,
      "start_minute": 0,
      "end_hour": 23,
      "end_minute": 30
    },
    "tuesday": {
      "start_hour": 6,
      "start_minute": 0,
      "end_hour": 23,
      "end_minute": 30
    },
    "wednesday": {
      "start_hour": 6,
      "start_minute": 0,
      "end_hour": 23,
      "end_minute": 30
    },
    "thursday": {
      "start_hour": 6,
      "start_minute": 0,
      "end_hour": 23,
      "end_minute": 30
    },
    "friday": {
      "start_hour": 6,
      "start_minute": 0,
      "end_hour": 23,
      "end_minute": 30
    },
    "saturday": {
      "start_hour": 6,
      "start_minute": 0,
      "end_hour": 23,
      "end_minute": 30
    },
    "sunday": {
      "start_hour": 6,
      "start_minute": 0,
      "end_hour": 23,
      "end_minute": 30
    }
  }
}'

Success · 201 Created

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "campaignId": "campaign_123",
    "advertiserId": "advertiser_123",
    "merchantId": "merchant_123",
    "platform": "google",
    "status": "active",
    "budget": 1,
    "maxCpc": 0.1,
    "countryCode": "UG",
    "country": "Uganda",
    "schedule": {
      "monday": {
        "start_hour": 6,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 30
      },
      "tuesday": {
        "start_hour": 6,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 30
      },
      "wednesday": {
        "start_hour": 6,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 30
      },
      "thursday": {
        "start_hour": 6,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 30
      },
      "friday": {
        "start_hour": 6,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 30
      },
      "saturday": {
        "start_hour": 6,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 30
      },
      "sunday": {
        "start_hour": 6,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 30
      }
    }
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

See Campaign response fields ↓
PATCH/v1/api/advertising/campaignUpdate managed campaign

Update managed campaign

Forward stored campaignId and advertiserId. timeZone cannot be updated; omit it. Validate budget, CPC and schedule.

Request fields

FieldTypeMeaning
platformstringManaged provider.google
statusstringRequested campaign state.active · inactive
budgetnumberAverage daily budget in USD.
maxCpcnumberMaximum USD cost per click.
countryCodestringTarget country code.
countrystringTarget country name.
scheduleobjectAll seven day names required; start must precede end.

Request

cURL
curl --request PATCH \
  --url "https://api.tecapy.com/v1/api/advertising/campaign" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID" \
  --header "Content-Type: application/json" \
  --data '{
  "budget": 2,
  "maxCpc": 0.1
}'

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "campaignId": "campaign_123",
    "advertiserId": "advertiser_123",
    "merchantId": "merchant_123",
    "platform": "google",
    "status": "active",
    "budget": 1,
    "maxCpc": 0.1,
    "countryCode": "UG",
    "country": "Uganda",
    "schedule": {
      "monday": {
        "start_hour": 6,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 30
      },
      "tuesday": {
        "start_hour": 6,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 30
      },
      "wednesday": {
        "start_hour": 6,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 30
      },
      "thursday": {
        "start_hour": 6,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 30
      },
      "friday": {
        "start_hour": 6,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 30
      },
      "saturday": {
        "start_hour": 6,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 30
      },
      "sunday": {
        "start_hour": 6,
        "start_minute": 0,
        "end_hour": 23,
        "end_minute": 30
      }
    }
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

See Campaign response fields ↓
GET/v1/api/advertising/analyticsGet campaign analytics

Get campaign analytics

Requires from/to. Server forwards the stored advertiserId and campaignId.

Query parameters: from, to.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/advertising/analytics?from=2026-11-01T00%3A00%3A00Z&to=2026-12-01T00%3A00%3A00Z" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "clicks": 12,
    "impressions": 400,
    "cost": 0.8,
    "conversions": 2,
    "conversionValue": 9000,
    "currency": "USD"
  }
}
Try this request

Reads data from the production API.

GET/v1/api/advertising/keywordsGet clicked search keywords

Get clicked search keywords

Requires from/to. Only keywords with clicks are shown, not all search appearances.

Query parameters: from, to.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/advertising/keywords?from=2026-11-01T00%3A00%3A00Z&to=2026-12-01T00%3A00%3A00Z" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": [
    {
      "keyword": "yellow cleaning sponge",
      "clicks": 1,
      "impressions": 13,
      "cost": 0.01
    }
  ]
}
Try this request

Reads data from the production API.

GET/v1/api/advertising/product-issuesGet Merchant Center issues

Get Merchant Center issues

Use the stored merchantId. Return severity, description, detail, documentation and applicable countries. Some issues are informational.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/advertising/product-issues" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": [
    {
      "productId": "prod_123",
      "title": "Yellow sponge",
      "issues": []
    }
  ]
}
Try this request

Reads data from the production API.

Endpoint reference

Payments

Create payment links to recharge your advertising wallet, pay the one-time USD 300 storefront license, or subscribe to an Independent integration or APIs & MCP (platform api) for USD 60 per month. currency is required for each request. Returned amount is in that currency; amountUsd is the USD charge. Follow paymentLink to pay; creating a link does not confirm payment.

POST/v1/api/payments/depositRecharge wallet

Recharge wallet

Send currency for local payment and amount in USD. Only deposits accept an amount; the backend converts it into the requested local currency.

Request fields

FieldTypeMeaning
currencyRequiredstringLocal currency for the payment link, for example UGX.
amountRequirednumberWallet deposit amount in USD, not local currency.

Request

cURL
curl --request POST \
  --url "https://api.tecapy.com/v1/api/payments/deposit" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID" \
  --header "Content-Type: application/json" \
  --data '{
  "currency": "UGX",
  "amount": 2
}'

Success · 201 Created

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "type": "deposit",
    "amountUsd": 2,
    "currency": "UGX",
    "amount": 7200,
    "paymentLink": "<payment_link>",
    "payment_id": "<payment_id>"
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

POST/v1/api/payments/licensePay storefront license

Pay storefront license

Send currency only. The one-time license price is fixed at USD 300; do not send amount or amountUsd.

Request fields

FieldTypeMeaning
currencyRequiredstringLocal currency for the payment link, for example UGX.

Request

cURL
curl --request POST \
  --url "https://api.tecapy.com/v1/api/payments/license" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID" \
  --header "Content-Type: application/json" \
  --data '{
  "currency": "UGX"
}'

Success · 201 Created

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "type": "license",
    "amountUsd": 300,
    "currency": "UGX",
    "amount": 1080000,
    "paymentLink": "<payment_link>",
    "payment_id": "<payment_id>"
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

POST/v1/api/payments/subscriptions/{platform}Start integration subscription

Start integration subscription

Send currency only and choose the integration platform in the URL: google, meta, tiktok, x, reddit, pinterest, snapchat, bing or api (APIs & MCP). The price is fixed at USD 60 per month; do not send amount or amountUsd. The response type is the platform, and renewsOn is returned only for subscriptions.

Request fields

FieldTypeMeaning
currencyRequiredstringLocal currency for the payment link, for example UGX.

Request

cURL
curl --request POST \
  --url "https://api.tecapy.com/v1/api/payments/subscriptions/your_platform" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID" \
  --header "Content-Type: application/json" \
  --data '{
  "currency": "UGX"
}'

Success · 201 Created

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "type": "google",
    "amountUsd": 60,
    "currency": "UGX",
    "renewsOn": "2026-12-10T00:00:00Z",
    "amount": 216000,
    "paymentLink": "<payment_link>",
    "payment_id": "<payment_id>"
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

Endpoint reference

Wallet, licenses & billing

Read balances and entitlements. Use Payments to create wallet, license or integration payment links. Clients cannot set balances, licenses or transaction payment states.

GET/v1/api/walletGet verified wallet balance

Get verified wallet balance

Wallet funds and ad spend are USD.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/wallet" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "balance": 40,
    "currency": "USD"
  }
}
Try this request

Reads data from the production API.

GET/v1/api/transactionsList payment history

List payment history

Cursor-paginated payment history.

Query parameters: from, to.

Pagination: limit (1–100, default 20), cursor (opaque). For the first page, omit cursor. For the next page, replace your_next_cursor in the example with meta.nextCursor, keeping the same filters and sort. Stop when meta.hasMore is false.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/transactions?from=2026-11-01T00%3A00%3A00Z&to=2026-12-01T00%3A00%3A00Z&limit=20&cursor=your_next_cursor" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": [
    {
      "id": "transaction_123",
      "amount": 30,
      "currency": "USD",
      "reason": "wallet",
      "createdAt": "2026-11-09T12:00:00Z"
    }
  ],
  "meta": {
    "nextCursor": null,
    "hasMore": false
  }
}
Try this request

Reads data from the production API.

GET/v1/api/licensesGet licenses & subscriptions

Get licenses & subscriptions

isActive may be true for a trial. isTrial:true does not mean paid; users can still subscribe.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/licenses" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "storefront": {
      "isActive": true,
      "isTrial": true,
      "expiresOn": "2026-12-09T00:00:00Z"
    },
    "integrations": {
      "google": {
        "isActive": true,
        "isTrial": false,
        "renewsOn": "2026-12-09T00:00:00Z"
      }
    }
  }
}
Try this request

Reads data from the production API.

GET/v1/api/exchange-ratesGet payment quote

Get payment quote

Use currency and amountUsd. Return local units per USD; USD-to-local multiplies by rate. Payment uses backend-verified quotes.

Query parameters: currency, amountUsd.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/exchange-rates?currency=UGX&amountUsd=30" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "currency": "UGX",
    "amountUsd": 30,
    "rate": 3600,
    "amount": 108000
  }
}
Try this request

Reads data from the production API.

Endpoint reference

Management & notifications

Sensitive operations require the appropriate store-owner authorization. API access never grants platform-team or cross-store access.

POST/v1/api/transfersInvite store manager or owner

Invite store manager or owner

Creates an invitation. Full transfer removes the original owner after acceptance; partial adds shared management. Acceptance requires the recipient to sign in to Tecapy.

Request fields

FieldTypeMeaning
emailRequiredstringRecipient email.
transferRequiredstringFull removes the original owner’s access after acceptance; partial adds shared management.full · partial

Request

cURL
curl --request POST \
  --url "https://api.tecapy.com/v1/api/transfers" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID" \
  --header "Content-Type: application/json" \
  --data '{
  "email": "manager@example.com",
  "transfer": "partial"
}'

Success · 201 Created

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "id": "transfer_123",
    "status": "pending",
    "emailSent": true,
    "email": "manager@example.com",
    "transfer": "partial"
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

POST/v1/api/access-reportsEmail an access report

Email an access report

Send the report to a confirmed email via user_report with storeName resolved server-side.

Request fields

FieldTypeMeaning
emailRequiredstringRequired. See the downloadable contract and request example.

Request

cURL
curl --request POST \
  --url "https://api.tecapy.com/v1/api/access-reports" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID" \
  --header "Content-Type: application/json" \
  --data '{
  "email": "owner@example.com"
}'

Success · 201 Created

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "emailSent": true
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

GET/v1/api/notifications/devicesList notification devices

List notification devices

Return deviceId, token, updatedAt and userId for registered devices. Treat push tokens as confidential.

Pagination: limit (1–100, default 20), cursor (opaque). For the first page, omit cursor. For the next page, replace your_next_cursor in the example with meta.nextCursor, keeping the same filters and sort. Stop when meta.hasMore is false.

Request

cURL
curl --request GET \
  --url "https://api.tecapy.com/v1/api/notifications/devices?limit=20&cursor=your_next_cursor" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": [
    {
      "deviceId": "device_123",
      "token": "<device_push_token>",
      "updatedAt": "2026-11-05T00:00:00Z",
      "userId": "<user_id>"
    }
  ],
  "meta": {
    "nextCursor": null,
    "hasMore": false
  }
}
Try this request

Reads data from the production API.

See Device response fields ↓
PUT/v1/api/notifications/devices/{deviceId}Register notification device

Register notification device

Send deviceId and token only. deviceId must match the URL. Do not send updatedAt or userId; they are assigned by the server. Browser must first grant notification permission; registration alone cannot grant it.

Request fields

FieldTypeMeaning
deviceIdRequiredstringDevice identifier. Must match deviceId in the request URL.
tokenRequiredstringDevice push token. Treat as confidential.

Request

cURL
curl --request PUT \
  --url "https://api.tecapy.com/v1/api/notifications/devices/your_device_id" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID" \
  --header "Content-Type: application/json" \
  --data '{
  "deviceId": "device_123",
  "token": "<device_push_token>"
}'

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": {
    "deviceId": "device_123",
    "token": "<device_push_token>",
    "updatedAt": "2026-11-05T00:00:00Z",
    "userId": "<user_id>"
  }
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

See Device response fields ↓
DELETE/v1/api/notifications/devices/{deviceId}Disable notifications on a device

Disable notifications on a device

Delete the saved device token.

Request

cURL
curl --request DELETE \
  --url "https://api.tecapy.com/v1/api/notifications/devices/your_device_id" \
  --header "Authorization: Bearer $TECAPY_API_KEY" \
  --header "X-Project-ID: $TECAPY_PROJECT_ID"

Success · 200 OK

JSON
{
  "success": true,
  "message": "Success",
  "data": null
}
Try this request

This request changes real store data. Review the body and identifiers before sending.

Data shapes

Resource fields.

Required fields apply to creation or replacement. PATCH accepts a subset, but the resulting resource must remain valid. The OpenAPI file includes nested schemas and all operation-specific fields.

Product
FieldTypeMeaning
idstringRead onlyOpaque resource ID.
projectIdstringRead onlyStore project ID, resolved from X-Project-ID.
slugstringRead onlyServer-generated product slug.
nameRequiredstringProduct title, natural capitalization, maximum 100 characters.
brandRequiredstringBrand or Unbranded.
categoryRequiredstringCategory display name.
categoryIdRequiredstringOpaque resource ID.
descriptionRequiredstringPlain-text description.
priceRequirednumberRegular price in the product currency.
discountPricenumber / nullOptional sale price, greater than zero and lower than price; null removes the discount.
currencyRequiredstringISO 4217 currency code.
conditionRequiredstringProduct condition.new · used · refurbished
inStockRequiredbooleanWhether the product is available.
imageRequiredstringCover image: one public HTTPS URL.
imagesarray<string>Additional image URLs, as strings, not objects. The cover image is separate in image; maximum six images including the cover.
facebookVideostring / nullFacebook video URL, or null.
tiktokVideostring / nullTikTok video URL, or null.
youtubeVideostring / nullYouTube video URL, or null.
createdAtstringRead onlyServer-generated UTC timestamp.
updatedAtstringRead onlyServer-generated UTC timestamp.
Category
FieldTypeMeaning
idstringRead onlyOpaque resource ID.
nameRequiredstringCategory name.
slugstringRead onlyServer-generated category slug.
createdAtstringRead onlyServer-generated UTC timestamp.
UpdatedAtstringRead onlyServer-generated UTC timestamp.
Store
FieldTypeMeaning
idstringRead onlyOpaque resource ID.
namestringBusiness name.
slugstringRead onlyStorefront slug. Cannot be changed through the API.
descriptionstringWhat the business does.
countrystringCountry name.
countryCodestringISO 3166-1 alpha-2 country code.
currencystringStore base currency.
phoneNumberstringInternational phone number including country code.
contactEmailstringBusiness contact email.
addressstringStreet address.
citystringCity.
statestringState or region.
zipCodestringPostal code.
googleMapsstringGoogle Maps embed URL for the store location.
workingHoursarray<object>Three groups, each once: Mon-Fri, Sat, Sun. Each entry has day, isOpen, open and close. Times are local HH:mm. isOpen:false means closed. PATCH replaces the entire array.
statusstringRead onlyPlatform-controlled publication status.
createdAtstringRead onlyServer-generated UTC timestamp.
updatedAtstringRead onlyServer-generated UTC timestamp.
Order
FieldTypeMeaning
idRequiredstringRead onlyOpaque resource ID.
createdAtRequiredstringRead onlyServer-generated UTC timestamp.
typeRequiredstringRecord type.order · whatsapp · call
currencyRequiredstringRecord currency.
productNameRequiredstringProduct name, or Store enquiry for a general call/WhatsApp record.
totalRequirednumberRecorded total; general store enquiries may have zero value.
customerNamestringCheckout customer name; absent on basic enquiry records.
customerEmailstringCheckout customer email.
customerPhonestringCustomer phone, when supplied.
apartmentstringApartment/unit.
citystringDelivery city.
countrystringDelivery country code.
streetAddressstringDelivery street address.
postalCodestringDelivery postal code.
deliveryFeenumberDelivery fee.
subtotalnumberItems subtotal.
fulfillmentstringCheckout fulfillment method.delivery · pickup
orderStatusstringCheckout fulfillment status.Processing · Shipped · Delivered · Cancelled
paymentMethodstringPayment provider/method identifier, for example dpo.
paymentStatusstringServer-verified payment state, for example pending.
itemsarray<object>Checkout product snapshots; absent on basic call/WhatsApp records.
Design
FieldTypeMeaning
checkoutobject / nullSee the OpenAPI schema for nested properties.
designCompleteboolean / nullWhether a design has been saved.
logoobject / null / nullMedia asset object, or null to clear it.
toolbarLogoobject / null / nullMedia asset object, or null to clear it.
footerLogoobject / null / nullMedia asset object, or null to clear it.
logoVisibilityobject / nullSee the OpenAPI schema for nested properties.
heroobject / nullSee the OpenAPI schema for nested properties.
paymentIconsarray / nullSee the OpenAPI schema for nested properties.
policiesobject / nullStore pages keyed by about, faq, payments, privacy, returns, shipping or terms. Save body and published under the page key.
productCardobject / nullSee the OpenAPI schema for nested properties.
productMediastring / nullProduct details layout.grid · slideshow ·
schemaVersioninteger / nullRead onlyServer-controlled design schema version.
socialLinksobject / nullSocial platform names mapped to public profile URLs.
themeobject / nullSee the OpenAPI schema for nested properties.
crawlersEnabledboolean / nullAllow search engines to crawl the dedicated store domain.
tagManagerstring / nullRead onlyGoogle Tag Manager container ID.
googleSiteVerificationstring / nullRead onlyGoogle verification content token.
currencySettingsobject / nullSee the OpenAPI schema for nested properties.
updatedAtstring / nullRead onlyServer-generated UTC timestamp.
feedAccessobject / nullRead onlyServer-managed feed access metadata. Returned by GET; never send in PATCH.
Gateway
FieldTypeMeaning
providerstringGateway identifier.flutterwave · paystack · pesapal · stripe · dpo · paypal
isActivebooleanConnection status.
credentialsRequiredobjectWrite onlyProvider-specific secret fields. PayPal uses client_id and client_secret. Never returned by GET.
Domain
FieldTypeMeaning
idstringRead onlyOpaque resource ID.
hostnamestringHostname only, without protocol or path.
statusstringRead onlyServer-managed registration state, such as ACT or PEN.
renewStatusstringRead onlyServer-managed renewal state.
DomainContact
FieldTypeMeaning
firstNameRequiredstringRegistrant first name.
lastNameRequiredstringRegistrant surname.
eMailRequiredstringRegistrant email.
phoneCountryCodeRequiredstringCountry calling code.
phoneAreaCodeRequiredstringFirst three digits of national phone number.
phoneRequiredstringRemaining national phone number.
countryRequiredstringCountry code.
addressRequiredstringStreet name.
addressNumberRequiredintegerBuilding or address number.
cityRequiredstringCity.
statestringRegion.
postalCodeRequiredstringPostal code.
slugRequiredstringStore slug.
DnsRecord
FieldTypeMeaning
idstringRead onlyOpaque resource ID.
nameRequiredstringRecord host/name.
typeRequiredstringRecord type.A · AAAA · CNAME · MX · TXT · NS · SOA · CAA · SRV
valueRequiredstringRecord target/value.
ttlRequiredintegerSee the OpenAPI schema for nested properties.
priorityintegerSee the OpenAPI schema for nested properties.
Campaign
FieldTypeMeaning
campaignIdstringRead onlyOpaque resource ID.
advertiserIdstringRead onlyOpaque resource ID.
merchantIdstringRead onlyOpaque resource ID.
platformRequiredstringManaged provider.google
statusRequiredstringRequested campaign state.active · inactive
budgetRequirednumberAverage daily budget in USD.
maxCpcRequirednumberMaximum USD cost per click.
countryCodeRequiredstringTarget country code.
countryRequiredstringTarget country name.
scheduleRequiredobjectAll seven day names required; start must precede end.
timeZonestringIANA timezone. Accepted only when creating a campaign; cannot be updated. Omit if unknown.
Transfer
FieldTypeMeaning
idstringRead onlyOpaque resource ID.
statusstringRead onlyInvitation status.
emailRequiredstringRecipient email.
transferRequiredstringFull removes the original owner’s access after acceptance; partial adds shared management.full · partial
Device
FieldTypeMeaning
deviceIdRequiredstringDevice identifier. Must match deviceId in the request URL.
tokenRequiredstringDevice push token. Treat as confidential.
updatedAtstringRead onlyServer-generated UTC timestamp.
userIdstringRead onlyServer-managed user ID.
AdIntegration
FieldTypeMeaning
platformstringIntegration platform.google · meta · tiktok · x · reddit · pinterest · snapchat · bing · google_tag
modestringConnection management mode.managed · independent
isActivebooleanWhether this integration is active.
CustomDomain
FieldTypeMeaning
firstNameRequiredstringRegistrant first name.
lastNameRequiredstringRegistrant surname.
eMailRequiredstringRegistrant email.
phoneCountryCodeRequiredstringCountry calling code.
phoneAreaCodeRequiredstringFirst three digits of national phone number.
phoneRequiredstringRemaining national phone number.
countryRequiredstringCountry code.
addressRequiredstringStreet name.
addressNumberRequiredintegerBuilding or address number.
cityRequiredstringCity.
stateRequiredstringRegion.
postalCodeRequiredstringPostal code.
domainNameRequiredstringPurchased domain hostname.
statusstringRead onlyACT means active. PEN means pending: the user has not completed payment.ACT · PEN
expirationDatenumberRead onlyExpiration time as Unix seconds.
domainIdintegerRead onlyRegistrar domain ID.
contactHandlestringRead onlyRegistrar contact handle.
authCodestringRead onlyDomain authorization code. Treat as confidential.
DesignAsset
FieldTypeMeaning
idstring / nullAsset ID.
pathstring / nullRead onlyServer-managed media storage path. Returned by GET; omit from PATCH.
typestring / nullMedia MIME type, such as image/webp.
urlstring / nullPublic HTTPS asset URL.
Checkout
FieldTypeMeaning
countryDeliveryFeesobject / nullCountry codes mapped to delivery fees in the checkout currency.
currencystring / nullCheckout currency.
deliveryEnabledboolean / nullOffer delivery.
deliveryFeenumber / nullDefault delivery fee.
enabledboolean / nullEnable checkout.
methodsarray / nullSee the OpenAPI schema for nested properties.
phoneRequiredboolean / nullRequire customer phone.
pickupEnabledboolean / nullOffer store pickup.
whatsappEnabledboolean / nullEnable WhatsApp checkout.

Errors that tell you what to fix.

JSON
{
  "success": false,
  "message": "<error_message>",
  "error": {
    "code": "<ERROR_CODE>",
    "details": "<error_details>"
  }
}
StatusMeaningNext step
400Invalid requestCheck syntax, headers and query parameters.
401Invalid or revoked keyCheck Authorization or generate a replacement in the CRM.
403Access deniedCheck the project ID, store permissions and required license.
404Not foundCheck the ID; cross-store resources are never disclosed.
409ConflictCheck duplicate resources or the current resource state.
422Validation failedRead error.details and correct the request.
429Rate limitedWait for Retry-After before retrying.
500 / 503Temporary service failureRetry with backoff after checking whether the previous request completed.

Every success uses {success:true,message:"Success",data:...}. Every error uses {success:false,message:...,error:{code:...,details:...}}. Error codes are machine-readable strings such as NOT_FOUND; details explains the failure. If a server supplies an X-Request-ID, share it with support, never your key. Documentation values in angle brackets are placeholders, not real credentials or user data.

Ready to connect your store?

Generate your credentials, save them securely, and build against this versioned contract.

Open API settings →

Need help with your integration?

Contact our team for help connecting your tools to Tecapy. Include the endpoint and error message, but never send your API key.

Email info@tecapy.com →