Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 46 additions & 74 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,13 @@ If you need support using AfterShip products, please contact support@aftership.c
- [Constructor](#constructor)
- [Example](#example)
- [Rate Limiter](#rate-limiter)
- [On successful requests](#on-successful-requests)
- [On rate-limited requests](#on-rate-limited-requests)
- [Error Handling](#error-handling)
- [Error List](#error-list)
- [Endpoints](#endpoints)
- [/estimated-delivery-date](#estimated-delivery-date)
- [/trackings](#trackings)
- [/couriers](#couriers)
- [/courier-connections](#courier-connections)
- [/estimated-delivery-date](#estimated-delivery-date)
- [Help](#help)
- [License](#license)

Expand All @@ -39,8 +37,8 @@ Before you begin to integrate:

### API and SDK Version

- SDK Version: 16.0.0
- API Version: 2026-01
- SDK Version: 17.0.0
- API Version: 2026-07

## Quick Start

Expand Down Expand Up @@ -94,53 +92,26 @@ aftership.tracking

See the [Rate Limit](https://www.aftership.com/docs/tracking/quickstart/rate-limit) to understand the AfterShip rate limit policy.

The API returns the current rate limit status in the headers of **every** response, and the SDK exposes them on both successful and failed requests, so you can monitor your consumption proactively instead of waiting for `429` errors.

| Header | Description |
| ----------------------- | ---------------------------------------------------- |
| `x-ratelimit-limit` | The rate limit ceiling for the current endpoint per second |
| `x-ratelimit-remaining` | The number of requests left for the 1-second window |
| `x-ratelimit-reset` | The Unix timestamp when the rate limit will be reset |

> Note: header names in `response_headers` are lower-cased.

### On successful requests
The API returns its current rate limit status in the headers of every response, and the SDK exposes these headers on both successful responses and rate-limited errors, so you can monitor your consumption proactively instead of waiting for `429` errors.

Every successful response contains a `response_headers` object alongside `data` (available since v15.0.0):
| Header | Description |
| ----------------------- | ---------------------------------------------------------- |
| `X-RateLimit-Limit` | The rate limit ceiling for the current endpoint per second |
| `X-RateLimit-Remaining` | The number of requests left for the 1-second window |
| `X-RateLimit-Reset` | The Unix timestamp when the rate limit will be reset |

```typescript
import { AfterShip } from "@aftership/tracking-sdk";

const aftership = new AfterShip({ api_key: "<your_api_key>" });

const result = await aftership.tracking.getTrackings();
Every successful response exposes a `response_headers` object alongside `data` (header names are lower-cased). Taking the Quick Start example above:

console.log(result.data.trackings);

// Rate limit status for this endpoint
const limit = Number(result.response_headers["x-ratelimit-limit"]);
```javascript
const remaining = Number(result.response_headers["x-ratelimit-remaining"]);
const resetAt = Number(result.response_headers["x-ratelimit-reset"]);

if (remaining <= 1) {
// Throttle or defer lower-priority workflows before hitting the limit
// Throttle or defer lower-priority requests until `resetAt`
}
```

### On rate-limited requests

When the limit is exceeded, the SDK throws an `AftershipError` with `code = TOO_MANY_REQUEST`. The same headers are available on the error:

```typescript
try {
await aftership.tracking.getTrackings();
} catch (e) {
if (e.code === "TOO_MANY_REQUEST") {
const resetAt = Number(e.response_headers["x-ratelimit-reset"]);
// Wait until resetAt before retrying
}
}
```
When the rate limit is exceeded, the request fails with a `429` error that carries the same headers — see [Error Handling](#error-handling).

## Error Handling

Expand Down Expand Up @@ -184,15 +155,13 @@ The SDK will return an error object when there is any error during the request,
| INTERNAL_ERROR | 502 | 502 | Something went wrong on AfterShip&#39;s end. |
| INTERNAL_ERROR | 503 | 503 | Something went wrong on AfterShip&#39;s end. |
| INTERNAL_ERROR | 504 | 504 | Something went wrong on AfterShip&#39;s end. |
| |

|

## Endpoints

The AfterShip instance has the following properties which are exactly the same as the API endpoints:

- estimatedDeliveryDate
- Prediction for the Estimated Delivery Date
- Batch prediction for the Estimated Delivery Date
- tracking
- Get trackings
- Create a tracking
Expand All @@ -210,34 +179,9 @@ The AfterShip instance has the following properties which are exactly the same a
- Get courier connection by id
- Update courier connection by id
- Delete courier connection by id

### /estimated-delivery-date

**POST** /estimated-delivery-date/predict

```javascript
const predictRequestBody = {
slug: "valid_value",
origin_address: {}, // EstimatedDeliveryDateRequestOriginAddress
destination_address: {}, // EstimatedDeliveryDateRequestDestinationAddress
};

aftership.estimatedDeliveryDate
.predict(predictRequestBody)
.then((result) => console.log(result))
.catch((e) => console.log(e));
```

**POST** /estimated-delivery-date/predict-batch

```javascript
const predictBatchRequestBody = {};

aftership.estimatedDeliveryDate
.predictBatch(predictBatchRequestBody)
.then((result) => console.log(result))
.catch((e) => console.log(e));
```
- estimatedDeliveryDate
- Prediction for the Estimated Delivery Date
- Batch prediction for the Estimated Delivery Date

### /trackings

Expand Down Expand Up @@ -410,6 +354,34 @@ aftership.courierConnection
.catch((e) => console.log(e));
```

### /estimated-delivery-date

**POST** /estimated-delivery-date/predict

```javascript
const predictRequestBody = {
slug: "valid_value",
origin_address: {}, // EstimatedDeliveryDateRequestOriginAddress
destination_address: {}, // EstimatedDeliveryDateRequestDestinationAddress
};

aftership.estimatedDeliveryDate
.predict(predictRequestBody)
.then((result) => console.log(result))
.catch((e) => console.log(e));
```

**POST** /estimated-delivery-date/predict-batch

```javascript
const predictBatchRequestBody = {};

aftership.estimatedDeliveryDate
.predictBatch(predictBatchRequestBody)
.then((result) => console.log(result))
.catch((e) => console.log(e));
```

## Help

If you get stuck, we're here to help:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aftership/tracking-sdk",
"version": "16.0.0",
"version": "17.0.0",
"description": "Tracking NodeJS SDK",
"main": "dist/aftership.js",
"types": "dist/aftership.d.ts",
Expand Down
6 changes: 3 additions & 3 deletions src/aftership.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
* This code was auto generated by AfterShip SDK Generator.
* Do not edit the class manually.
*/
import { EstimatedDeliveryDateApi } from "./api/EstimatedDeliveryDate";
import { TrackingApi } from "./api/Tracking";
import { CourierApi } from "./api/Courier";
import { CourierConnectionApi } from "./api/CourierConnection";
import { EstimatedDeliveryDateApi } from "./api/EstimatedDeliveryDate";
import { AftershipError, AfterShipErrorCodes } from "./error";
import { AuthType } from "./lib/authentication";
import {
Expand Down Expand Up @@ -33,10 +33,10 @@ export interface Options {
const SDK_ENV_PREFIX = "AFTERSHIP_TRACKING_SDK_";

export class AfterShip {
public readonly estimatedDeliveryDate: EstimatedDeliveryDateApi;
public readonly tracking: TrackingApi;
public readonly courier: CourierApi;
public readonly courierConnection: CourierConnectionApi;
public readonly estimatedDeliveryDate: EstimatedDeliveryDateApi;
private readonly options: Options;

constructor(options?: Options) {
Expand Down Expand Up @@ -100,10 +100,10 @@ export class AfterShip {
user_agent: this.options.user_agent,
proxy: parseProxy(this.options.proxy),
});
this.estimatedDeliveryDate = new EstimatedDeliveryDateApi(request);
this.tracking = new TrackingApi(request);
this.courier = new CourierApi(request);
this.courierConnection = new CourierConnectionApi(request);
this.estimatedDeliveryDate = new EstimatedDeliveryDateApi(request);
}

private validateOptions() {
Expand Down
8 changes: 4 additions & 4 deletions src/api/Courier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
*/
import { Request } from "../lib/request";
import { AftershipError, AfterShipErrorCodes } from "../error";
import { DetectCourierRequest } from "../model/DetectCourierRequest";
import { DetectCourierResponse } from "../model/DetectCourierResponse";
import { GetCouriersResponse } from "../model/GetCouriersResponse";
import { GetCouriersQuery } from "../model/GetCouriersQuery";
import { DetectCourierRequest } from "../model/DetectCourierRequest";
import { DetectCourierResponse } from "../model/DetectCourierResponse";

export class CourierApi {
private readonly request: Request;
Expand All @@ -23,7 +23,7 @@ export class CourierApi {
query?: GetCouriersQuery,
headers?: { [key: string]: any },
): Promise<GetCouriersResponse> {
const url = `/tracking/2026-01/couriers`;
const url = `/tracking/2026-07/couriers`;
return this.request.makeRequest<GetCouriersResponse>({
url: url,
method: "GET",
Expand All @@ -38,7 +38,7 @@ export class CourierApi {
body: DetectCourierRequest,
headers?: { [key: string]: any },
): Promise<DetectCourierResponse> {
const url = `/tracking/2026-01/couriers/detect`;
const url = `/tracking/2026-07/couriers/detect`;
return this.request.makeRequest<DetectCourierResponse>({
url: url,
method: "POST",
Expand Down
18 changes: 9 additions & 9 deletions src/api/CourierConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
*/
import { Request } from "../lib/request";
import { AftershipError, AfterShipErrorCodes } from "../error";
import { GetCourierConnectionsResponse } from "../model/GetCourierConnectionsResponse";
import { GetCourierConnectionsQuery } from "../model/GetCourierConnectionsQuery";
import { PostCourierConnectionsRequest } from "../model/PostCourierConnectionsRequest";
import { PostCourierConnectionsResponse } from "../model/PostCourierConnectionsResponse";
import { GetCourierConnectionsByIdResponse } from "../model/GetCourierConnectionsByIdResponse";
import { PutCourierConnectionsByIdRequest } from "../model/PutCourierConnectionsByIdRequest";
import { PutCourierConnectionsByIdResponse } from "../model/PutCourierConnectionsByIdResponse";
import { DeleteCourierConnectionsByIdResponse } from "../model/DeleteCourierConnectionsByIdResponse";
import { GetCourierConnectionsResponse } from "../model/GetCourierConnectionsResponse";
import { GetCourierConnectionsQuery } from "../model/GetCourierConnectionsQuery";
import { PostCourierConnectionsRequest } from "../model/PostCourierConnectionsRequest";
import { PostCourierConnectionsResponse } from "../model/PostCourierConnectionsResponse";

export class CourierConnectionApi {
private readonly request: Request;
Expand All @@ -27,7 +27,7 @@ export class CourierConnectionApi {
query?: GetCourierConnectionsQuery,
headers?: { [key: string]: any },
): Promise<GetCourierConnectionsResponse> {
const url = `/tracking/2026-01/courier-connections`;
const url = `/tracking/2026-07/courier-connections`;
return this.request.makeRequest<GetCourierConnectionsResponse>({
url: url,
method: "GET",
Expand All @@ -42,7 +42,7 @@ export class CourierConnectionApi {
body: PostCourierConnectionsRequest,
headers?: { [key: string]: any },
): Promise<PostCourierConnectionsResponse> {
const url = `/tracking/2026-01/courier-connections`;
const url = `/tracking/2026-07/courier-connections`;
return this.request.makeRequest<PostCourierConnectionsResponse>({
url: url,
method: "POST",
Expand All @@ -63,7 +63,7 @@ export class CourierConnectionApi {
AfterShipErrorCodes.BAD_REQUEST,
);
}
const url = `/tracking/2026-01/courier-connections/${id}`;
const url = `/tracking/2026-07/courier-connections/${id}`;
return this.request.makeRequest<GetCourierConnectionsByIdResponse>({
url: url,
method: "GET",
Expand All @@ -84,7 +84,7 @@ export class CourierConnectionApi {
AfterShipErrorCodes.BAD_REQUEST,
);
}
const url = `/tracking/2026-01/courier-connections/${id}`;
const url = `/tracking/2026-07/courier-connections/${id}`;
return this.request.makeRequest<PutCourierConnectionsByIdResponse>({
url: url,
method: "PATCH",
Expand All @@ -105,7 +105,7 @@ export class CourierConnectionApi {
AfterShipErrorCodes.BAD_REQUEST,
);
}
const url = `/tracking/2026-01/courier-connections/${id}`;
const url = `/tracking/2026-07/courier-connections/${id}`;
return this.request.makeRequest<DeleteCourierConnectionsByIdResponse>({
url: url,
method: "DELETE",
Expand Down
8 changes: 4 additions & 4 deletions src/api/EstimatedDeliveryDate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
*/
import { Request } from "../lib/request";
import { AftershipError, AfterShipErrorCodes } from "../error";
import { EstimatedDeliveryDateRequest } from "../model/EstimatedDeliveryDateRequest";
import { PredictResponse } from "../model/PredictResponse";
import { PredictBatchRequest } from "../model/PredictBatchRequest";
import { PredictBatchResponse } from "../model/PredictBatchResponse";
import { EstimatedDeliveryDateRequest } from "../model/EstimatedDeliveryDateRequest";
import { PredictResponse } from "../model/PredictResponse";

export class EstimatedDeliveryDateApi {
private readonly request: Request;
Expand All @@ -23,7 +23,7 @@ export class EstimatedDeliveryDateApi {
body: EstimatedDeliveryDateRequest,
headers?: { [key: string]: any },
): Promise<PredictResponse> {
const url = `/tracking/2026-01/estimated-delivery-date/predict`;
const url = `/tracking/2026-07/estimated-delivery-date/predict`;
return this.request.makeRequest<PredictResponse>({
url: url,
method: "POST",
Expand All @@ -38,7 +38,7 @@ export class EstimatedDeliveryDateApi {
body: PredictBatchRequest,
headers?: { [key: string]: any },
): Promise<PredictBatchResponse> {
const url = `/tracking/2026-01/estimated-delivery-date/predict-batch`;
const url = `/tracking/2026-07/estimated-delivery-date/predict-batch`;
return this.request.makeRequest<PredictBatchResponse>({
url: url,
method: "POST",
Expand Down
Loading