Note: The V3 API is still a work in progress. If the endpoint you are looking for is not here, please refer back to the V2 version. The V3 API explorer is still in progress
The Wishpost API will be using OAuth to authenticate in order to offer better security for its users
All dates and times in our API are returned in the same format. It is in the form YYYY-MM-DDTHH:mm:ss.sss±XX:ZZ
or YYYY-MM-DDTHH:mm:ss.sssZ
, where 'Z' represents UTC timezone.
When sending timestamps in URL parameters or the request body, millisecond is optional and will defaults to 0 if not provided.
YYYY
is the yearMM
is the monthDD
is the dayHH
is the hour (in 24-hour clock format)mm
is the minutesss.sss
is the seconds and milliseconds±XX:ZZ
is the UTC offset of the form +XX:ZZ or -XX:ZZ where XX is a 2-digit string giving the number of UTC offset hours, and ZZ is a 2-digit string giving the number of UTC offset minutes.Every response returned from the Wishpost API will have the same schema. This schema is intended to give you a predictable manner to check the status of your request and know where to get the data. Each response will have the following top level attributes: message, code and data.
Attributes
Message | A message describing the error that happened, example: "We could not find a product for id: '5d30f60e0a6fc464f4f376b0'" |
---|---|
Code | A unique number which represents the error that has occurred, example: 1008 or 0 if success. |
Data | For errors this will be empty. |
General Error Code
Error Type | Code | Message |
---|---|---|
InvalidParam | 1000 | Invalid Param |
MissingParam | 1001 | Missing Param |
TokenExpired | 1007 | The access token has been Expired |
TokenRevoked | 1008 | The access token has been revoked |
RequireRealNameVerification | 1014 | Please go to wishpost and do the real-name verification. |
TokenDoesNotExist | 1020 | Access token is not exsited |
InvalidRequestBodyParam | 1100 | Invalid Request Body Param |
InvalidRequestBody | 1101 | Invalid Request Body |
InvalidAuthorizationHeader | 1102 | Badly formatted authorization header |
InsufficientScope | 1103 | The wishpost user does not have sufficient roles to use this API |
UnauthorizedAccess | 4000 | Unauthorized access on this API |
HttpsRequired | 4000 | This API Requires the use of HTTPS |
MethodNotAllowed | 4005 | Please use ** instead of ** |
RateLimitIpLevelError | 4290 | This api can be called no more than ** times per minute per *, please slow down and call later |
RateLimitUserLevelError | 4291 | This api can be called no more than * times per minute per *, please slow down and call later |
RateLimitIpUserLevelError | 4292 | This api can be called no more than * times per minute per *, please slow down and call later |
RateLimitIpAgentLevelError | 4293 | This api can be called no more than * times per minute per *, please slow down and call later |
RateLimitIpUserAgentLevelError | 4294 | This api can be called no more than * times per minute per *, please slow down and call later |
RateLimitAppLevelError | 4295 | This api can be called no more than * times per minute per *, please slow down and call later |
RateLimitIpAppLevelError | 4296 | This api can be called no more than * times per minute per **, please slow down and call later |
UnknownError | 9000 | Unknown Error |
All GET endpoints (except OAuth) support a fields parameter which allows for requesting a partial response. Any fields specified in the response schema of an endpoint can be selected. The top level attribute data
can be ignored when using the fields parameter.
Syntax
/
to select nested field: field1/nested_field
( )
to select multiple nested fields: field1(nested_field1,nested_field2)
*
for wildcard selection: field1/nested_field/*
Example:
https://wishpost.cn/api/v3/demo/get?fields=title,items(id,info/name)
Which would result in the following partial response:
{
"title": "demo",
"items": [
{
"id": "1",
"info": {
"name": "demo_item_1"
}
}, {
"id": "2",
"info": {
"name": "demo_item_2"
}
},
...
]
}
You can optionally specify locale in order to translate error messages into your language. If none is provided, your default locale will be used.
Supported locales: 'en', 'zh'
Parameters
locale | (optional) The language you want the error message to be translated in. If none is provided, your default locale will be used. Supported locales: 'en', 'zh'. |
---|
Sorting is available for most endpoints that return a collection (list) of objects. Each collection has a different set of enabled parameters for sorting, so please check specific collection section for detail.
Append sort_by={parameter_name}.{asc|desc}
in your API request where parameter_name
is a valid sortable parameter of that endpoint.
Example:
/api/v3/announcements?sort_by=publish_time.asc
All bulk-fetching API methods that return lists of resource support pagination.
These methods commonly take at least 3 parameters: limit
, {attribute}_min
, {attribute}_max
. Attribute can be id
, create_at
, etc., depending on each specific method.
For instance, you make a request to get a list of penalties /api/v3/announcements?limit=20&created_at_max=2020-04-08T23:59:59Z&sort_by=created_at_max.desc
,
which means to fetch 20 penalities sorted by their creation time, with the most recent one being created before 2020-04-08T23:59:59Z
.
Assume that the response contains 20 announcement
objects with the last object being announcement_foo
,
then your subsequent request can be /api/v3/announcements?limit=20&created_at_max={announcement_foo.create_at}&sort_by=created_at_max.desc
to fetch the next page of list.
Note that when fetching next page using id_min
or id_max
, you need to perform +/- 1
(correspondingly) on the last object's ID in the current page, as id_min
and id_max
are inclusive. (All V3 API resources' IDs are either integer or BSON object ID - a hex number).
Each API request is associated with a unique identifier. You can find this value in response headers, under Wish-Request-Id
.
When you need to contact us about a specific request, please provide this ID to ensure the fastest possible reply
For all requests that require OAuth2 authentication, the access token must be provided in the Authorization
request header in the following format: Authorization: Bearer <token>
For example:
Authorization: Bearer 3d6e2d71bc464e42bfbdb081afb73c1e
Security Scheme Type | OAuth2 |
---|---|
authorizationCode OAuth Flow | Authorization URL: https://wishpost.cn/v3/oauth/authorize Token URL: https://wishpost.cn/api/v3/oauth/access_token Refresh URL: https://wishpost.cn/api/v3/oauth/refresh_token Scopes:
|
An access token and a refresh token will be returned through this API. Your application should store both tokens. The access token is used to make authorized requests and the refresh token is used to obtain new access tokens. For security reasons, the access token will expire after 30 days. When the access token expires, please use refresh_token API to get new ones.
client_id required | string <object-id> Your app's client ID |
code required | string The authorization code you received |
grant_type required | string The string 'authorization_code' |
redirect_uri required | string Your app's redirect uri that you specified when you created the app |
Authorization required | string The Authorization value is 'Basic client_id:client_secret base64 code' |
Content-Type required | string Content-Type is 'application/x-www-form-urlencoded' |
import requests url = "https://wishpost.cn/api/v3/oauth/access_token" querystring = {"client_id":"SOME_STRING_VALUE","code":"SOME_STRING_VALUE","grant_type":"SOME_STRING_VALUE","redirect_uri":"SOME_STRING_VALUE"} headers = { 'authorization': "Bearer REPLACE_BEARER_TOKEN", 'content-type': "SOME_STRING_VALUE" } response = requests.request("GET", url, headers=headers, params=querystring) print(response.text)
{- "username": "string",
- "scopes": [
- "string"
], - "user_id": "string",
- "access_token": "string",
- "expires_in": 0,
- "expiry_time": "2019-08-24T14:15:22Z",
- "refresh_token": "string"
}
This API will generate a new token without going through the full OAuth process again. Existing access tokens will be revoked after calling this API
client_id required | string <object-id> Your app's client ID |
grant_type required | string The string 'refresh_token' |
refresh_token required | string The refresh token |
Authorization required | string The Authorization value is 'Basic client_id:client_secret base64 code' |
Content-Type required | string Content-Type is 'application/x-www-form-urlencoded' |
import requests url = "https://wishpost.cn/api/v3/oauth/refresh_token" querystring = {"client_id":"SOME_STRING_VALUE","refresh_token":"SOME_STRING_VALUE","grant_type":"SOME_STRING_VALUE"} headers = { 'authorization': "Bearer REPLACE_BEARER_TOKEN", 'content-type': "SOME_STRING_VALUE" } response = requests.request("GET", url, headers=headers, params=querystring) print(response.text)
{- "username": "string",
- "scopes": [
- "string"
], - "user_id": "string",
- "access_token": "string",
- "expires_in": 0,
- "expiry_time": "2019-08-24T14:15:22Z",
- "refresh_token": "string"
}
This is a convenient endpoint for users to quickly verify if a given access token can be used.
import requests url = "https://wishpost.cn/api/v3/oauth/test" headers = {'authorization': 'Bearer REPLACE_BEARER_TOKEN'} response = requests.request("GET", url, headers=headers) print(response.text)
{- "user_id": "string"
}
import requests url = "https://wishpost.cn/api/v3/channels" headers = {'authorization': 'Bearer REPLACE_BEARER_TOKEN'} response = requests.request("GET", url, headers=headers) print(response.text)
[- {
- "pickup_services": [
- {
- "pickup_service_name": "string",
- "pickup_service_code": "string"
}
], - "channel_name_en": "string",
- "support_warehouses": true,
- "is_only_online_payment": true,
- "channel_name": "string",
- "otype": "string",
- "allow_battery": true,
- "is_registered": true,
- "warehouses": [
- {
- "warehouse_name": "string",
- "warehouse_code": 0,
- "warehouse_return_address": "string"
}
], - "sensitivity_types": [
- 0
]
}
]
Cancel orders due to some reasons. This API allow up to 100 requests in the request body. The response will include an array of the same size as the request array where each item represent a response to the corresponding request.
user.order.write
) cancel_reason_code required | string Enum: "USER_INCORRECT_CHANNEL" "USER_INCORRECT_PICKUP_TYPE" "USER_INCORRECT_CARRIER" "USER_INCORRECT_WAREHOUSE" "USER_INCORRECT_ADDRESS" "USER_INCORRECT_WEIGHT" "USER_INCORRECT_DECLEAR_VALUE" "USER_SYSTEM_TRACKING_ID_HAS_BEEN_USED" "USER_SYSTEM_TRACKING_ID_NOT_FOUND" "USER_SYSTEM_ERP_TRACKING_ID_NOT_FOUND" "USER_SYSTEM_LABEL_CANNOT_PRINT" "USER_SYSTEM_INVALID_LABEL" "USER_SYSTEM_LABEL_EXPIRED" "USER_CARRIER_NOT_PICKUP" "USER_CARRIER_NOT_IN_RANGE" "USER_CARRIER_CHANGE_TRACKING_ID" "USER_CARRIER_CANNOT_GET_PAID" "USER_CARRIER_NOT_RECEIVE_PARCEL" "USER_BIZ_BUYER_REFUND" "USER_BIZ_WRONG_PARCEL" "USER_BIZ_NEED_TO_COMBINE_ORDER" "USER_BIZ_NEED_TO_SPLIT_ORDER" "USER_BIZ_DUPLICATE_ORDER" "USER_OTHER_REASON" USER_INCORRECT_CHANNEL: 需更换渠道. USER_INCORRECT_PICKUP_TYPE: 需更换揽收方式. USER_INCORRECT_CARRIER: 需更换物流商. USER_INCORRECT_WAREHOUSE: 需更换仓库. USER_INCORRECT_ADDRESS: 需更换地址. USER_INCORRECT_WEIGHT: 需更换重量. USER_INCORRECT_DECLEAR_VALUE: 需更换申报价格. USER_SYSTEM_TRACKING_ID_HAS_BEEN_USED: 单号已被使用. USER_SYSTEM_TRACKING_ID_NOT_FOUND: 无法获取单号. USER_SYSTEM_ERP_TRACKING_ID_NOT_FOUND: ERP无法获取单号. USER_SYSTEM_LABEL_CANNOT_PRINT: 无法打印面单. USER_SYSTEM_INVALID_LABEL: 无效面单. USER_SYSTEM_LABEL_EXPIRED: 订单过期. USER_CARRIER_NOT_PICKUP: 物流商未取货. USER_CARRIER_NOT_IN_RANGE: 不在揽收范围. USER_CARRIER_CHANGE_TRACKING_ID: 物流商需更换单号. USER_CARRIER_CANNOT_GET_PAID: 物流商无法收款. USER_CARRIER_NOT_RECEIVE_PARCEL: 物流商未收到包裹. USER_BIZ_BUYER_REFUND: 买家要求退货. USER_BIZ_WRONG_PARCEL: 寄错货物. USER_BIZ_NEED_TO_COMBINE_ORDER: 需合并发货. USER_BIZ_NEED_TO_SPLIT_ORDER: 需拆分发货. USER_BIZ_DUPLICATE_ORDER: 重复下单. USER_OTHER_REASON: 其他原因. |
tracking_id required | string Tracking id of the order to be cancelled |
invalid_reason | string Required if |
[- {
- "cancel_reason_code": "USER_INCORRECT_CHANNEL",
- "tracking_id": "string",
- "invalid_reason": "string"
}
]
[- {
- "error_message": "string",
- "error_code": 0,
- "tracking_id": "string",
- "success": true
}
]