Skip to content

Merchant API v1 (1.0.0)

The Merchant API lets merchants integrate their own systems, such as a store or an ERP for which Hive has no native integration, with Hive.

You can create SKUs and orders, and read back the fulfillment and delivery status of orders. You can also work with other parts of Hive's warehouse management: restocking shipments, returns and warehouses.

The API does not give access to all the data and features of the Hive app. An access token belongs to one sales channel (shop): SKUs, orders and shipments are scoped to that shop, while restocking shipments, returns and warehouses are scoped to the merchant that owns it. If your platform is listed in Hive's integration list, you do not need this API.

Versioning

This is version 1 of the Merchant API. It stays available for existing integrations but is frozen: new features are only added to v2, and new integrations should use v2. The same access tokens work for both versions.

Access tokens

Every request must be authenticated with an API access token, sent as a bearer token in the Authorization header:

Authorization: Bearer your_api_token

Ask your account manager for a token. The production domain is https://app.hive.app, the staging domain is https://staging.app.hive.app.

A missing or unknown token is answered with 401 Unauthorized. A token that has expired, or whose sales channel is no longer active, is answered with 403 Forbidden.

Requests

Request bodies are JSON. Every request to v1 is read as JSON, whatever its Content-Type header says, but sending Content-Type: application/json is recommended. A body that is not valid JSON is answered with 400 Bad Request. Numeric properties of a request body also accept numeric strings, such as "42000", and a number sent for a string property is stored as its text.

Endpoints that take a whole resource (creating or updating an order, creating a SKU, and each item of a SKU bulk upsert) reject properties they do not know with 422 Unprocessable Entity; the properties they accept but ignore are listed as such. The other endpoints ignore unknown properties.

Errors

A failed request answers with a 4xx status code and a JSON body whose errors property is an array of human-readable messages:

{
  "success": false,
  "errors": ["Name can't be blank", "Merchant sku can't be blank"]
}

The common cases are 400 for a malformed request, 401 and 403 for authentication problems, 404 when the requested record does not exist or does not belong to you, 409 when a record with the same data already exists, 422 when the data is invalid, and 429 when the rate limit is exceeded.

Pagination

List endpoints, except GET /warehouses, are paginated. The response is an object with the records in data and the page information in pagination:

{
  "data": [],
  "pagination": {
    "current_page": 1,
    "item_count": 2,
    "page_count": 1,
    "items_per_page": 20
  }
}

Pass page to choose a page (it starts at 1, the default) and limit to choose the page size (default 20). A limit above 100 is treated as 100. A page past the last one returns an empty data array. pagination.page_count tells how many pages there are.

Most list endpoints also accept created_at[gt], created_at[gte], created_at[lt] and created_at[lte] to filter by creation time, as ISO 8601 date-times.

Rate Limiting

Requests are rate limited per sales channel, by default to 100 requests per calendar minute (UTC). If you have a valid use case for a higher limit, contact your account manager. Real-time updates are available through webhooks, so frequent polling should not be necessary.

Responses carry two headers with the current usage:

X-Rate-Limit-Used: 42
X-Rate-Limit-Max: 100

Requests over the limit are answered with 429 Too Many Requests and a Retry-After header giving the number of seconds until the next minute starts, for example Retry-After: 3.2.

Webhooks

Webhooks notify you of events as they happen, for example when the delivery status of a shipment changes. Hive sends an HTTP POST request with a JSON body to the URL you registered for the event. To set up webhooks, give your account manager the URL for each event you want to receive.

v1 webhooks are separate from v2 webhooks: a URL registered for v1 receives the v1 events below, whose body is the bare v1 resource (the same object the v1 endpoints return), with no envelope around it. See the webhooks section below for each event and its payload.

  • delivery_status_updated: the carrier delivery status of a shipment changed. The payload is a Shipment.
  • shipment_status_updated: the fulfillment status of a shipment changed. The payload is a Shipment.
  • restocking_shipment_status_updated: the status of a restocking shipment changed. The payload is a RestockingShipment.
  • return_status_updated: the status of a return changed. The payload is a Return.

Answer with a 2xx status to acknowledge a webhook; Hive does not follow redirects, and any status below 400 counts as received. Hive waits 5 seconds for the answer. A timeout, a connection failure or a 5xx status is retried with growing intervals, up to 12 attempts over about 11 to 13 hours; 429 answers are retried the same way, counted separately. Any other 4xx status is treated as a rejection of the payload and is not retried.

Webhook Security

Hive signs each webhook request with an x-hive-signature header whenever the sales channel has a valid API token (without one, the header is left out): the hex-encoded HMAC-SHA256 digest of the request body, keyed with your API token. If the sales channel has several valid tokens, the oldest one is the key. Ignore requests without this header or whose signature does not match.

def request_valid?(req) # req is a Rack::Request
  return false if !req.post?
  request_sig = req.get_header("HTTP_X_HIVE_SIGNATURE")
  expected_sig = OpenSSL::HMAC.hexdigest("sha256", ENV["API_TOKEN"], req.body.read)
  Rack::Utils.secure_compare(request_sig.to_s, expected_sig)
end

Webhook Reliability

Webhook handlers should be idempotent. Hive does not guarantee the order of the calls, and a retried call carries the same payload again. Each request has an x-hive-event-id header, which stays the same across the retries of one call. Compare the timestamps in the payload with the last update you stored, and ignore a payload older than what you have.

Download OpenAPI description
Languages
Servers
Mock server
https://developers.hive.app/_mock/merchant-api-v1/mapi_v1_oas31
Production API
https://app.hive.app/merchant_api/v1
Staging API
https://staging.app.hive.app/merchant_api/v1