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.
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.
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 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.
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.
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 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.
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.
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.
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.
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.
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.
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.
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
| Value | Meaning |
|---|---|
paid | Paid order waiting to be routed. Default for paid new orders. |
routed | Exported or sent to a 3PL/WMS by Omnifill. |
problem | Failed 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.
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
| Method | Path | Purpose |
|---|---|---|
POST | /api/auth/signup | Create a new account. Sets session cookie on success. |
POST | /api/auth/login | Log in with username or email and password. Sets session cookie. |
POST | /api/auth/logout | Invalidate the current session and clear the cookie. |
GET | /api/auth/me | Return 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
| Plan | Billing | Period extended after checkout |
|---|---|---|
monthly | Monthly recurring | ~32 days from purchase |
yearly | Annual 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 event | Effect on subscription record |
|---|---|
checkout.session.completed | Creates or activates a subscription for the customer email. Sets plan and initial period end. |
customer.subscription.updated | Updates status and current period end from the subscription object. |
customer.subscription.deleted | Sets status to cancelled. |
invoice.payment_succeeded | Sets 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.
Orders API
Endpoints
| Method | Path | Purpose |
|---|---|---|
GET | /api/orders | List all orders for the current account, joined with canonical product fields. |
POST | /api/orders/import | Bulk import normalized orders. |
PATCH | /api/orders/:id | Update an order's status. |
POST | /api/orders/:id/product | Assign an order to a canonical product and save an alias. |
DELETE | /api/orders | Delete 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.
| Field | Type | Description |
|---|---|---|
id | string | Omnifill ID in ABC-1234-DEFG format. |
source | string | Origin platform: stripe, paypal, shopify, woocommerce, kickstarter, or any custom string. |
date | string | Order date in YYYY-MM-DD format. |
first_name | string | Customer first name. |
last_name | string | Customer last name. |
email | string | Customer email address. |
phone | string | Customer phone number. |
address_line1 | string | Street address. |
city | string | City. |
postal_code | string | Postal or ZIP code. |
country | string | Two-letter country code (e.g. US, GB). |
product | string | Raw product name as received from the source. |
product_id | integer | ID of the assigned canonical product, or null. |
product_name | string | Canonical product name (joined), or null. |
product_sku | string | Canonical product SKU, or null. |
product_image_data | string | Product image as a data URL, or null. |
qty | integer | Quantity ordered. Defaults to 1. |
amount | string | Order total with 2 decimal places (e.g. "120.00"). |
currency | string | Lowercase ISO 4217 currency code. |
status | string | paid, routed, or problem. |
created_at | string | ISO 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
| Field | Aliases accepted | Required | Description |
|---|---|---|---|
source | - | Yes | Platform identifier. Use lowercase (e.g. stripe, paypal, shopify, woocommerce, kickstarter, csv). |
source_id | sourceId | Recommended | ID from the originating platform. Required for reliable deduplication. |
date | - | - | Order date, YYYY-MM-DD. |
firstName | first_name | - | Customer first name. |
lastName | last_name | - | Customer last name. |
email | - | - | Customer email. |
phone | - | - | Customer phone. |
addressLine1 | address_line1 | - | Street address. |
city | - | - | City. |
postalCode | postal_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 }
Products API
Endpoints
| Method | Path | Purpose |
|---|---|---|
GET | /api/products | List products with aliases, assigned order count, and remaining stock. |
GET | /api/products/stock | Slim stock summary - IDs, names, SKUs, and stock numbers only. |
POST | /api/products | Create a product. |
PATCH | /api/products/:id | Update a product. |
DELETE | /api/products/:id | Delete a product. Detaches linked orders by setting their product_id to null. |
Create / update fields
| Field | Aliases | Type | Description |
|---|---|---|---|
name | - | string | Canonical product name. Required. |
sku | - | string | Optional internal SKU. |
image_data | imageData | string | Product image as a data URL (PNG, JPEG, or WebP only; max ~800 KB). The dashboard resizes images to fit within 512x512 before uploading. |
no_fulfillment | noFulfillment | boolean | Marks products that should be skipped in fulfillment exports, such as digital items, tips, or add-ons that do not ship. |
track_stock | trackStock | boolean | Enables inventory counting for this product. |
stock_qty | stockQty | integer | Total units in stock before assigned orders are subtracted. |
aliases | - | array | Raw 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:
| Parameter | Values | Description |
|---|---|---|
range | 7, 30, 90, all | Rolling window in days. Default is all. |
from + to | YYYY-MM-DD | Custom 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
| Method | Path | Purpose |
|---|---|---|
GET | /api/stripe/status | Check if a Stripe account is connected and return the account ID. |
GET | /api/stripe/connect | Initiate OAuth - redirects to Stripe's authorization page. |
DELETE | /api/stripe/disconnect | Revoke access and remove stored Stripe credentials. |
POST | /api/stripe/sync | Pull orders from Stripe into Omnifill. |
POST /api/stripe/sync - sync modes and incremental behavior
| Mode | What it fetches |
|---|---|
charges (default) | All charges via /v1/charges. Best for accounts using the Charges API directly. |
checkout_sessions | Completed checkout sessions via /v1/checkout/sessions. Best for Stripe Checkout. |
payment_link | Sessions 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
| Method | Path | Purpose |
|---|---|---|
GET | /api/paypal/status | Check if a PayPal account is connected and return its email. |
GET | /api/paypal/connect | Initiate OAuth - redirects to PayPal's authorization page. |
DELETE | /api/paypal/disconnect | Remove stored PayPal credentials. |
POST | /api/paypal/sync | Pull 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 code | Omnifill status |
|---|---|
S (Success), P (Pending) | paid |
D (Denied), V (Reversed), F (Failed) | problem |
| any other | paid |
/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
| Method | Path | Purpose |
|---|---|---|
GET | /api/shopify/status | Check if a Shopify store is connected and return the shop domain. |
GET | /api/shopify/connect?shop=example.myshopify.com | Initiate OAuth - redirects to Shopify's authorization page. |
POST | /api/shopify/sync | Pull paid Shopify orders into Omnifill. |
DELETE | /api/shopify/disconnect | Remove 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_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
| Method | Path | Purpose |
|---|---|---|
GET | /api/woocommerce/status | Check if a WooCommerce store is connected and return its store URL. |
GET | /api/woocommerce/connect?store_url=https://example.com | Initiate WooCommerce app authorization. |
POST | /api/woocommerce/sync | Pull WooCommerce orders into Omnifill. |
DELETE | /api/woocommerce/disconnect | Remove 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.
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
| ID | What is checked |
|---|---|
web | Public marketing site at omnifill.net |
dashboard | Dashboard app at dashboard.omnifill.net |
api | API server health via GET /api/health |
stripe | Reachability of api.stripe.com |
paypal | Reachability 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.