Official Documentation

Omnifill Docs

Omnifill brings orders from payment processors, storefronts, and campaign exports into one normalized dashboard, then prepares those orders for 3PLs, WMS tools, and warehouse partners.

Dashboard

The dashboard at dashboard.omnifill.net is a browser-based React app for connecting sources, reviewing orders, defining shippable products, exporting fulfillment files, and monitoring analytics.

API

Every dashboard action is backed by a REST API. All endpoints live under https://dashboard.omnifill.net/api and authenticate via a session cookie.

Core Concepts

Sources

Sources are the places orders come from: Stripe, PayPal, Shopify, WooCommerce, and campaign CSVs such as Kickstarter, Indiegogo, or Gamefound. Each imported order keeps its source label and original source ID for traceability.

Normalized orders

Omnifill converts different source formats into one order schema: customer details, address fields, product name, quantity, amount, currency, source, status, and a stable Omnifill order ID.

Products

A product is the shippable item your warehouse needs to recognize. Raw names like "Deluxe box pledge" and "Deluxe board game reward" can both map to one product with a SKU, inventory setting, and fulfillment flag.

Aliases

Aliases connect raw source product names to canonical products. When a matching name appears on a future sync or CSV import, Omnifill assigns the product automatically.

Fulfillment exports

Exports turn selected orders into clean CSV files for 3PLs, WMS tools, and shipping aggregators. Products marked as not needing fulfillment are skipped, and missing warehouse-critical fields block clean export.

Deduplication

Each order carries a source label and a source_id from the originating platform. That pair is unique per account, so re-syncing or re-importing the same source data does not create duplicate orders.

Fulfillment Workflow

Omnifill is designed around one practical flow: bring orders in, make the data consistent, define what ships, and hand the clean result to the partner that fulfills it.

1. Connect or import sources

Use OAuth for live sources such as Stripe, PayPal, Shopify, and WooCommerce. Use CSV import for campaign and marketplace exports when a direct connection is not needed.

2. Review normalized orders

The Orders screen gives every order the same fields regardless of where it came from. Filter by source, status, date, country, or product assignment before fulfillment work starts.

3. Define products and SKUs

Create products for the items that physically ship, add aliases for messy source names, mark digital or non-shipping items as no fulfillment, and add SKUs used by your warehouse.

4. Export or route

Download fulfillment-ready CSVs using partner-oriented profiles and field mappings. Direct 3PL or WMS API pushes are available where supported and require saved partner credentials on the backend.

CSV export is the dependable fallback for fulfillment partners that still work from files. Direct API routing should be treated as partner-specific and confirmed during setup.

Data Formats

All data exchanged with the API uses these canonical formats. Incoming data is normalized on write; non-conforming values may be silently coerced.

Omnifill Order ID

Every order is assigned a unique Omnifill ID on creation. The format is three uppercase alphanumeric segments separated by hyphens:

ABC-1234-DEFG   (pattern: [A-Z0-9]{3}-[A-Z0-9]{4}-[A-Z0-9]{4})

This ID is stable and never changes. The original source ID (e.g. ch_xxx from Stripe) is stored separately as source_id.

Date

Dates are stored and returned as YYYY-MM-DD (ISO 8601, dashes). Dates with slashes (YYYY/MM/DD) are accepted on import and normalized automatically.

2026-05-02

Amount

Amounts are stored as strings with exactly two decimal places, not as floating-point numbers.

"120.00"

Stripe amounts are converted from integer cents (12000 becomes "120.00"). PayPal amounts are passed through from the transactions API.

Currency

Currency codes are lowercase ISO 4217. Uppercase input is normalized on write.

"usd"   "eur"   "gbp"

Order Status

ValueMeaning
paidPaid order waiting to be routed. Default for paid new orders.
routedExported or sent to a 3PL/WMS by Omnifill.
problemFailed payment, bad address, or other issue. Excluded from stock calculations.

Authentication

Omnifill uses cookie-based sessions. After a successful login or signup, the server sets an HttpOnly; SameSite=Strict cookie named p2s_token that is valid for 30 days. All authenticated API calls must include this cookie.

In curl, use a cookie jar: add -c cookies.txt on login to save the cookie, then -b cookies.txt on subsequent requests to send it. Or extract the token value and pass it directly with -b "p2s_token=VALUE".
Auth endpoints
MethodPathPurpose
POST/api/auth/signupCreate a new account. Sets session cookie on success.
POST/api/auth/loginLog in with username or email and password. Sets session cookie.
POST/api/auth/logoutInvalidate the current session and clear the cookie.
GET/api/auth/meReturn the current user profile and subscription status.

POST /api/auth/signup

curl -X POST https://dashboard.omnifill.net/api/auth/signup \
  -H "Content-Type: application/json" \
  -c cookies.txt \
  -d '{
    "username": "myusername",
    "email": "[email protected]",
    "password": "atleast6chars"
  }'

Returns 201 with { "username": "...", "email": "..." } and sets the session cookie. Password must be at least 6 characters. Both username and email must be unique (case-insensitive for email).

If a subscription was purchased with the same email before sign-up, it is automatically linked to the new account.

POST /api/auth/login

curl -X POST https://dashboard.omnifill.net/api/auth/login \
  -H "Content-Type: application/json" \
  -c cookies.txt \
  -d '{ "identifier": "myusername", "password": "mypassword" }'

The identifier field accepts either username or email address.

GET /api/auth/me

curl https://dashboard.omnifill.net/api/auth/me -b cookies.txt
{
  "username": "myusername",
  "email": "[email protected]",
  "hasStripeConnected": true,
  "hasPayPalConnected": false,
  "subscription": {
    "status": "active",
    "plan": "monthly",
    "currentPeriodEnd": "2026-06-02"
  }
}

Subscription status is one of: active, past_due, cancelled. The subscription field is null if no subscription record exists.

Subscriptions

Omnifill subscriptions are managed through Stripe. A webhook keeps subscription state in sync with Stripe events in real time.

Plans

PlanBillingPeriod extended after checkout
monthlyMonthly recurring~32 days from purchase
yearlyAnnual recurring~366 days from purchase

The plan is inferred from the Stripe checkout session in this order: the plan metadata field on the session or subscription, the session amount (amounts over $35.00 are treated as yearly), and finally the recurring interval from the Stripe line item price.

Webhook events handled

Stripe eventEffect on subscription record
checkout.session.completedCreates or activates a subscription for the customer email. Sets plan and initial period end.
customer.subscription.updatedUpdates status and current period end from the subscription object.
customer.subscription.deletedSets status to cancelled.
invoice.payment_succeededSets status to active and extends period end from the invoice line item.

Webhook endpoint

Configure a webhook in your Stripe dashboard pointing to:

POST https://dashboard.omnifill.net/api/webhooks/stripe

Set the STRIPE_WEBHOOK_SECRET environment variable to the signing secret Stripe provides. Requests are validated with HMAC-SHA256 and rejected if the timestamp is more than 5 minutes old.

The webhook endpoint reads the raw request body for signature verification. It must be registered before any body-parsing middleware in the request pipeline.

Orders API

Endpoints
MethodPathPurpose
GET/api/ordersList all orders for the current account, joined with canonical product fields.
POST/api/orders/importBulk import normalized orders.
PATCH/api/orders/:idUpdate an order's status.
POST/api/orders/:id/productAssign an order to a canonical product and save an alias.
DELETE/api/ordersDelete all orders and reset sync timestamps.
GET /api/orders - response schema

Returns an array of orders sorted by date descending, joined with canonical product fields when a product is assigned.

FieldTypeDescription
idstringOmnifill ID in ABC-1234-DEFG format.
sourcestringOrigin platform: stripe, paypal, shopify, woocommerce, kickstarter, or any custom string.
datestringOrder date in YYYY-MM-DD format.
first_namestringCustomer first name.
last_namestringCustomer last name.
emailstringCustomer email address.
phonestringCustomer phone number.
address_line1stringStreet address.
citystringCity.
postal_codestringPostal or ZIP code.
countrystringTwo-letter country code (e.g. US, GB).
productstringRaw product name as received from the source.
product_idintegerID of the assigned canonical product, or null.
product_namestringCanonical product name (joined), or null.
product_skustringCanonical product SKU, or null.
product_image_datastringProduct image as a data URL, or null.
qtyintegerQuantity ordered. Defaults to 1.
amountstringOrder total with 2 decimal places (e.g. "120.00").
currencystringLowercase ISO 4217 currency code.
statusstringpaid, routed, or problem.
created_atstringISO 8601 datetime when the record was created in Omnifill.
POST /api/orders/import - bulk import

Import an array of orders. Orders are deduplicated by source + source_id per account - re-importing the same order only updates the product assignment if it changed.

curl -X POST https://dashboard.omnifill.net/api/orders/import \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{
    "orders": [
      {
        "source": "kickstarter",
        "source_id": "backer-1001",
        "date": "2026-05-02",
        "firstName": "Mira",
        "lastName": "Stone",
        "email": "[email protected]",
        "country": "US",
        "product": "Deluxe board game",
        "qty": 2,
        "amount": "120.00",
        "currency": "usd"
      }
    ]
  }'

Returns: { "inserted": 1, "total": 1 }

If a product name matches an existing alias, the order is automatically assigned to the corresponding canonical product on import.

Import field reference

FieldAliases acceptedRequiredDescription
source-YesPlatform identifier. Use lowercase (e.g. stripe, paypal, shopify, woocommerce, kickstarter, csv).
source_idsourceIdRecommendedID from the originating platform. Required for reliable deduplication.
date--Order date, YYYY-MM-DD.
firstNamefirst_name-Customer first name.
lastNamelast_name-Customer last name.
email--Customer email.
phone--Customer phone.
addressLine1address_line1-Street address.
city--City.
postalCodepostal_code-Postal or ZIP code.
country--Two-letter country code.
product--Raw product name from the source.
qty--Quantity. Defaults to 1.
amount--Order total as a string or number.
currency--Lowercase ISO 4217. Defaults to usd.
status--Defaults to paid.
PATCH /api/orders/:id - update status

Update the status of a single order. Only the status field can be changed via this endpoint.

curl -X PATCH https://dashboard.omnifill.net/api/orders/ABC-1234-DEFG \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{ "status": "routed" }'

Valid values: paid, routed, problem. Returns { "ok": true }, or 404 if not found.

POST /api/orders/:id/product - assign product

Assign an order to a canonical product. Omnifill saves the raw product name on the order as an alias, and bulk-updates all other currently unassigned orders that share the same raw product name.

curl -X POST https://dashboard.omnifill.net/api/orders/ABC-1234-DEFG/product \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{ "product_id": 1 }'

Returns: { "ok": true, "product_id": 1 }

DELETE /api/orders - clear all orders

Deletes all orders for the current account and resets the Stripe and PayPal sync timestamps so the next sync fetches everything from scratch.

curl -X DELETE https://dashboard.omnifill.net/api/orders -b cookies.txt

Returns: { "ok": true, "deleted": 42 }

This is irreversible. Products and aliases are not affected.

Products API

Endpoints
MethodPathPurpose
GET/api/productsList products with aliases, assigned order count, and remaining stock.
GET/api/products/stockSlim stock summary - IDs, names, SKUs, and stock numbers only.
POST/api/productsCreate a product.
PATCH/api/products/:idUpdate a product.
DELETE/api/products/:idDelete a product. Detaches linked orders by setting their product_id to null.
Create / update fields
FieldAliasesTypeDescription
name-stringCanonical product name. Required.
sku-stringOptional internal SKU.
image_dataimageDatastringProduct image as a data URL (PNG, JPEG, or WebP only; max ~800 KB). The dashboard resizes images to fit within 512x512 before uploading.
no_fulfillmentnoFulfillmentbooleanMarks products that should be skipped in fulfillment exports, such as digital items, tips, or add-ons that do not ship.
track_stocktrackStockbooleanEnables inventory counting for this product.
stock_qtystockQtyintegerTotal units in stock before assigned orders are subtracted.
aliases-arrayRaw product names to recognize as this product. Each element is a plain string or { "raw_name": "...", "source": "..." }. If a name is already aliased to another product, it is reassigned.

Example: create a product with aliases

curl -X POST https://dashboard.omnifill.net/api/products \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{
    "name": "Deluxe board game",
    "sku": "DGB-001",
    "no_fulfillment": false,
    "track_stock": true,
    "stock_qty": 50,
    "aliases": [
      { "raw_name": "Deluxe box pledge", "source": "stripe" },
      "Deluxe board game reward"
    ]
  }'

Returns 201 with { "ok": true, "product": { ... } } containing the full product object including computed stock fields.

GET /api/products - response schema
[
  {
    "id": 1,
    "name": "Deluxe board game",
    "sku": "DGB-001",
    "image_data": null,
    "track_stock": true,
    "stock_qty": 50,
    "assigned_qty": 44,
    "order_count": 22,
    "remaining_stock": 6,
    "aliases": [
      { "raw_name": "Deluxe box pledge",        "source": "stripe" },
      { "raw_name": "Deluxe board game reward",  "source": null }
    ],
    "created_at": "2026-05-01T10:00:00",
    "updated_at": "2026-05-02T09:30:00"
  }
]

remaining_stock is null when inventory tracking is off. assigned_qty sums order quantities where status != 'problem'. order_count is the number of distinct orders assigned to this product.

Stock calculation

Use GET /api/products/stock for a compact view without aliases or image data.

remaining_stock = stock_qty - assigned_qty

If track_stock is false, remaining_stock is null. remaining_stock is clamped to 0 and will not go negative in API responses.

[
  {
    "id": 1,
    "name": "Deluxe board game",
    "sku": "DGB-001",
    "track_stock": true,
    "stock_qty": 50,
    "assigned_qty": 44,
    "remaining_stock": 6
  }
]

Analytics API

The analytics endpoint aggregates order data into KPIs and breakdowns. All values are scoped to the current account.

GET /api/analytics

Date filtering

Pass either a preset rolling window or a custom date range as query parameters:

ParameterValuesDescription
range7, 30, 90, allRolling window in days. Default is all.
from + toYYYY-MM-DDCustom inclusive date range. Both must be present; from must be ≤ to. Takes priority over range.
curl "https://dashboard.omnifill.net/api/analytics?range=30" -b cookies.txt

curl "https://dashboard.omnifill.net/api/analytics?from=2026-04-01&to=2026-04-30" -b cookies.txt

Response

{
  "kpis": {
    "totalRevenue":    3480.00,
    "totalOrders":     87,
    "fulfillmentRate": 0.644,
    "avgOrderValue":   40.00,
    "currency":        "usd"
  },
  "ordersOverTime": [
    { "date": "2026-04-01", "count": 5, "revenue": 200.00 }
  ],
  "bySource": [
    { "source": "stripe",      "count": 60, "revenue": 2400.00 },
    { "source": "kickstarter", "count": 27, "revenue": 1080.00 }
  ],
  "byStatus": [
    { "status": "paid",   "count": 31 },
    { "status": "routed", "count": 56 }
  ],
  "byCountry": [
    { "country": "US", "count": 42 },
    { "country": "GB", "count": 18 }
  ]
}

fulfillmentRate is a decimal 0-1 (1.0 = 100% routed). currency reflects the most common currency among filtered orders. byCountry returns the top 10 countries; blank and N/A entries are excluded.

Stripe Integration

Connect a Stripe account via OAuth to sync charges and checkout sessions. After the first full sync, subsequent syncs are incremental.

Endpoints
MethodPathPurpose
GET/api/stripe/statusCheck if a Stripe account is connected and return the account ID.
GET/api/stripe/connectInitiate OAuth - redirects to Stripe's authorization page.
DELETE/api/stripe/disconnectRevoke access and remove stored Stripe credentials.
POST/api/stripe/syncPull orders from Stripe into Omnifill.
POST /api/stripe/sync - sync modes and incremental behavior
ModeWhat it fetches
charges (default)All charges via /v1/charges. Best for accounts using the Charges API directly.
checkout_sessionsCompleted checkout sessions via /v1/checkout/sessions. Best for Stripe Checkout.
payment_linkSessions for a specific payment link. Requires paymentLinkId starting with plink_.
// Sync all charges
curl -X POST https://dashboard.omnifill.net/api/stripe/sync \
  -H "Content-Type: application/json" -b cookies.txt \
  -d '{ "mode": "charges" }'

// Sync a specific payment link
curl -X POST https://dashboard.omnifill.net/api/stripe/sync \
  -H "Content-Type: application/json" -b cookies.txt \
  -d '{ "mode": "payment_link", "paymentLinkId": "plink_xxx" }'

// Force a full re-sync
curl -X POST https://dashboard.omnifill.net/api/stripe/sync \
  -H "Content-Type: application/json" -b cookies.txt \
  -d '{ "mode": "charges", "force": true }'

The first sync is always a full sync - it deletes existing Stripe orders for the account and fetches everything. Subsequent syncs are incremental, fetching only items created after the last sync timestamp minus a 1-hour buffer to catch stragglers. Pass "force": true to reset to a full sync at any time.

Product name extraction (charges)

Omnifill tries to extract a product name from these charge fields in order: description, metadata.product_name, metadata.product, metadata.item. Generic strings like "Stripe Payment" and "Stripe Checkout" are discarded and left blank.

GET /api/stripe/status - response
{
  "connected": true,
  "accountId": "acct_xxx"
}

PayPal Integration

Connect a PayPal account via OAuth to sync transactions by date range. Access tokens are refreshed automatically when they expire.

Endpoints
MethodPathPurpose
GET/api/paypal/statusCheck if a PayPal account is connected and return its email.
GET/api/paypal/connectInitiate OAuth - redirects to PayPal's authorization page.
DELETE/api/paypal/disconnectRemove stored PayPal credentials.
POST/api/paypal/syncPull transactions from PayPal into Omnifill.
POST /api/paypal/sync

Sync transactions for a date range. Default is the last 30 days.

// Default: last 30 days
curl -X POST https://dashboard.omnifill.net/api/paypal/sync \
  -H "Content-Type: application/json" -b cookies.txt -d '{}'

// Custom date range
curl -X POST https://dashboard.omnifill.net/api/paypal/sync \
  -H "Content-Type: application/json" -b cookies.txt \
  -d '{
    "startDate": "2026-01-01T00:00:00+0000",
    "endDate":   "2026-03-31T23:59:59+0000"
  }'

Returns: { "inserted": 12, "total": 12 }

Transaction status mapping

PayPal status codeOmnifill status
S (Success), P (Pending)paid
D (Denied), V (Reversed), F (Failed)problem
any otherpaid
If the access token is expired, Omnifill automatically refreshes it using the stored refresh token. If the refresh token is also expired, reconnect via /api/paypal/connect.
GET /api/paypal/status - response
{
  "connected": true,
  "email": "[email protected]"
}

Shopify Integration

Connect a Shopify store via OAuth to import paid orders into the unified Omnifill order table. Shopify order lines are normalized into order records with customer, address, product, amount, currency, and source metadata.

Endpoints
MethodPathPurpose
GET/api/shopify/statusCheck if a Shopify store is connected and return the shop domain.
GET/api/shopify/connect?shop=example.myshopify.comInitiate OAuth - redirects to Shopify's authorization page.
POST/api/shopify/syncPull paid Shopify orders into Omnifill.
DELETE/api/shopify/disconnectRemove stored Shopify credentials.
POST /api/shopify/sync
curl -X POST https://dashboard.omnifill.net/api/shopify/sync -b cookies.txt

Returns { "inserted": 12, "total": 12 }. Repeated syncs are deduplicated by source and source_id.

Shopify OAuth must be configured with SHOPIFY_CLIENT_ID, SHOPIFY_CLIENT_SECRET, and a dashboard callback URL before stores can connect.

WooCommerce Integration

Connect a WooCommerce store through app authorization to sync completed or processing orders into Omnifill. Use the public WordPress store URL where WooCommerce is installed.

Endpoints
MethodPathPurpose
GET/api/woocommerce/statusCheck if a WooCommerce store is connected and return its store URL.
GET/api/woocommerce/connect?store_url=https://example.comInitiate WooCommerce app authorization.
POST/api/woocommerce/syncPull WooCommerce orders into Omnifill.
DELETE/api/woocommerce/disconnectRemove stored WooCommerce credentials.
POST /api/woocommerce/sync
curl -X POST https://dashboard.omnifill.net/api/woocommerce/sync -b cookies.txt

Returns { "inserted": 12, "total": 12 }. Repeated syncs are deduplicated by source and source_id.

WooCommerce sync works best when products have stable names and SKUs. Map those product names to Omnifill products before exporting to a warehouse profile.

Status API

Omnifill monitors five components every 5 minutes and retains 90 days of history. These endpoints power the public status page at omnifill.net/status. No authentication is required.

Monitored components
IDWhat is checked
webPublic marketing site at omnifill.net
dashboardDashboard app at dashboard.omnifill.net
apiAPI server health via GET /api/health
stripeReachability of api.stripe.com
paypalReachability of api-m.paypal.com
GET /api/status/current

Returns the most recent check result for each component.

curl https://dashboard.omnifill.net/api/status/current
{
  "web":       { "status": "operational", "latency_ms": 42,  "checked_at": "2026-05-02T14:30:00" },
  "dashboard": { "status": "operational", "latency_ms": 38,  "checked_at": "2026-05-02T14:30:00" },
  "api":       { "status": "operational", "latency_ms": 5,   "checked_at": "2026-05-02T14:30:00" },
  "stripe":    { "status": "operational", "latency_ms": 180, "checked_at": "2026-05-02T14:30:00" },
  "paypal":    { "status": "operational", "latency_ms": 210, "checked_at": "2026-05-02T14:30:00" }
}

Status values: operational, outage, or unknown (no data recorded yet).

GET /api/status/history

Returns a daily aggregated status across all components for the last 90 days.

curl https://dashboard.omnifill.net/api/status/history
[
  { "day": "2026-04-01", "status": "operational" },
  { "day": "2026-04-02", "status": "outage" }
]

A day is outage if any component had any failed check that day, otherwise operational.

API Tutorial

A quick end-to-end walkthrough using a cookies.txt cookie jar to persist the session across calls.

End-to-end walkthrough

1. Log in

curl -X POST https://dashboard.omnifill.net/api/auth/login \
  -H "Content-Type: application/json" -c cookies.txt \
  -d '{ "identifier": "yourusername", "password": "yourpassword" }'

2. Create a product

curl -X POST https://dashboard.omnifill.net/api/products \
  -H "Content-Type: application/json" -b cookies.txt \
  -d '{
    "name": "Deluxe board game",
    "sku": "DGB-001",
    "track_stock": true,
    "stock_qty": 50
  }'

3. Import orders

If an order's product name matches an existing alias, Omnifill assigns it automatically on import.

curl -X POST https://dashboard.omnifill.net/api/orders/import \
  -H "Content-Type: application/json" -b cookies.txt \
  -d '{
    "orders": [
      {
        "source": "kickstarter",
        "source_id": "backer-1001",
        "date": "2026-05-02",
        "firstName": "Mira",
        "lastName": "Stone",
        "email": "[email protected]",
        "country": "US",
        "product": "Deluxe board game",
        "qty": 2,
        "amount": "120.00",
        "currency": "usd"
      }
    ]
  }'

4. Assign an unrecognized order to a product

Assigning an order saves its raw product name as an alias and bulk-updates all other unassigned orders with the same name.

curl -X POST https://dashboard.omnifill.net/api/orders/ABC-1234-DEFG/product \
  -H "Content-Type: application/json" -b cookies.txt \
  -d '{ "product_id": 1 }'

5. Mark an order routed

curl -X PATCH https://dashboard.omnifill.net/api/orders/ABC-1234-DEFG \
  -H "Content-Type: application/json" -b cookies.txt \
  -d '{ "status": "routed" }'

6. Check remaining stock

curl https://dashboard.omnifill.net/api/products/stock -b cookies.txt

7. Pull analytics for the last 30 days

curl "https://dashboard.omnifill.net/api/analytics?range=30" -b cookies.txt

FAQ

What order sources does Omnifill support?

Omnifill supports Stripe, PayPal, Shopify, and WooCommerce connections, plus CSV imports for crowdfunding and marketplace exports such as Kickstarter, Indiegogo, and Gamefound.

Does Omnifill replace my storefront, payment processor, 3PL, or WMS?

No. Omnifill sits between those systems. It collects order data from the places where you sell, normalizes it, and prepares the clean order set your fulfillment partner needs.

Can I use Omnifill if my warehouse only accepts CSV files?

Yes. CSV export is the standard fallback. The Export screen includes fulfillment-oriented profiles, field mappings, validation, and a preview so you can generate files that warehouses can map during intake.

Can Omnifill push orders directly to my 3PL or WMS?

Direct API routing is partner-specific and available where supported. It requires partner credentials and setup on the backend. If a partner does not have a supported direct route yet, use CSV export.

How does Omnifill prevent duplicate orders?

Each imported order stores the source platform and the source order ID. Omnifill uses that pair per account for deduplication, so re-running a sync or re-importing the same CSV does not create a second copy of the same order.

What are products and aliases for?

Products represent the items your fulfillment partner needs to pick and ship. Aliases let messy source names map to the right product automatically, so names from Stripe, Shopify, Kickstarter, or PayPal can all resolve to one SKU.

Can I skip products that do not need fulfillment?

Yes. Mark a product as no_fulfillment to keep it out of fulfillment exports. This is useful for digital goods, tips, warranties, or add-ons that do not physically ship.

Does Omnifill charge transaction fees?

No transaction fee is added by Omnifill. Current pricing is a 14-day free trial, then $12/month or $120/year. Your payment processors, storefronts, warehouses, and shipping providers may charge their own fees.

Is there help for Kickstarter creators?

Yes. Selected Kickstarter campaigns can receive 3 months free and personalized onboarding. Apply at https://omnifill.net/kickstarter.

What data does Omnifill store?

Omnifill stores account details, source connection tokens, imported order data, products, aliases, export settings, and subscription status as needed to run the service. See the privacy policy for the full legal description.

How do I contact support?

Email [email protected]. Include the source you are using, a short description of the issue, and any affected Omnifill order IDs if the problem involves specific orders.