Skip to content
Open
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
185 changes: 105 additions & 80 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ If you need support using AfterShip products, please contact support@aftership.c
- [Error Handling](#error-handling)
- [Error List](#error-list)
- [Endpoints](#endpoints)
- [/trackings](#trackings)
- [/couriers](#couriers)
- [/courier-connections](#courier-connections)
- [/estimated-delivery-date](#estimated-delivery-date)
- [/trackings](#trackings)
- [Help](#help)
- [License](#license)

Expand All @@ -38,16 +38,16 @@ Before you begin to integrate:

### API and SDK Version

- SDK Version: 11.0.0
- API Version: 2026-01
- SDK Version: 12.0.0
- API Version: 2026-07
## Quick Start

### Installation
```bash
<dependency>
<groupId>com.aftership</groupId>
<artifactId>tracking-sdk</artifactId>
<version>11.0.0</version>
<version>12.0.0</version>
</dependency>
```

Expand Down Expand Up @@ -95,6 +95,31 @@ public class App {

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

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.

| 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 |

Every successful response exposes `getResponseHeader()` (a `Map<String, List<String>>`) alongside `getData()`. Header names are case-insensitive per the HTTP spec, so normalize when looking up. Taking the Quick Start example above:

```java
Map<String, List<String>> headers = response.getResponseHeader();
int remaining = headers.entrySet().stream()
.filter(e -> e.getKey().equalsIgnoreCase("x-ratelimit-remaining"))
.map(e -> Integer.parseInt(e.getValue().get(0)))
.findFirst()
.orElse(-1);

if (remaining >= 0 && remaining <= 1) {
// Throttle or defer lower-priority requests
}
```

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

The SDK will return an error object when there is any error during the request, with the following specification:
Expand Down Expand Up @@ -144,14 +169,6 @@ The SDK will return an error object when there is any error during the request,

The AfterShip SDK has the following resource which are exactly the same as the API endpoints:

- TrackingResource
- Get trackings
- Create a tracking
- Get a tracking by ID
- Update a tracking by ID
- Delete a tracking by ID
- Retrack an expired tracking by ID
- Mark tracking as completed by ID
- CourierResource
- Get couriers
- Detect courier
Expand All @@ -164,169 +181,177 @@ The AfterShip SDK has the following resource which are exactly the same as the A
- EstimatedDeliveryDateResource
- Prediction for the Estimated Delivery Date
- Batch prediction for the Estimated Delivery Date
- TrackingResource
- Get trackings
- Create a tracking
- Get a tracking by ID
- Update a tracking by ID
- Delete a tracking by ID
- Retrack an expired tracking by ID
- Mark tracking as completed by ID

### /trackings
**GET** /trackings
### /couriers
**GET** /couriers

```java
GetTrackingsResponse response = TrackingResource.getTrackings()
GetCouriersResponse response = CourierResource.getCouriers()
.fetch();
System.out.println(response.getData());
```

**POST** /trackings
**POST** /couriers/detect

```java
CreateTrackingRequest request = new CreateTrackingRequest();
DetectCourierRequest request = new DetectCourierRequest();
request.setTrackingNumber("valid_value");
CreateTrackingResponse response = TrackingResource.createTracking()
.setCreateTrackingRequest(request)
DetectCourierResponse response = CourierResource.detectCourier()
.setDetectCourierRequest(request)
.create();
System.out.println(response.getData());
```

**GET** /trackings/{id}
### /courier-connections
**GET** /courier-connections

```java
GetTrackingByIdResponse response = TrackingResource.getTrackingById()
.setId("valid_value")
GetCourierConnectionsResponse response = CourierConnectionResource.getCourierConnections()
.fetch();
System.out.println(response.getData());
```

**PUT** /trackings/{id}
**POST** /courier-connections

```java
UpdateTrackingByIdRequest request = new UpdateTrackingByIdRequest();
UpdateTrackingByIdResponse response = TrackingResource.updateTrackingById()
.setId("valid_value")
.setUpdateTrackingByIdRequest(request)
.update();
PostCourierConnectionsRequest request = new PostCourierConnectionsRequest();
request.setCourierSlug("valid_value");
request.setCredentials();
PostCourierConnectionsResponse response = CourierConnectionResource.postCourierConnections()
.setPostCourierConnectionsRequest(request)
.create();
System.out.println(response.getData());
```

**DELETE** /trackings/{id}
**GET** /courier-connections/{id}

```java
DeleteTrackingByIdResponse response = TrackingResource.deleteTrackingById()
GetCourierConnectionsByIdResponse response = CourierConnectionResource.getCourierConnectionsById()
.setId("valid_value")
.delete();
.fetch();
System.out.println(response.getData());
```

**POST** /trackings/{id}/retrack
**PATCH** /courier-connections/{id}

```java
RetrackTrackingByIdResponse response = TrackingResource.retrackTrackingById()
PutCourierConnectionsByIdRequest request = new PutCourierConnectionsByIdRequest();
request.setCredentials();
PutCourierConnectionsByIdResponse response = CourierConnectionResource.putCourierConnectionsById()
.setId("valid_value")
.create();
.setPutCourierConnectionsByIdRequest(request)
.update();
System.out.println(response.getData());
```

**POST** /trackings/{id}/mark-as-completed
**DELETE** /courier-connections/{id}

```java
MarkTrackingCompletedByIdRequest request = new MarkTrackingCompletedByIdRequest();
MarkTrackingCompletedByIdResponse response = TrackingResource.markTrackingCompletedById()
DeleteCourierConnectionsByIdResponse response = CourierConnectionResource.deleteCourierConnectionsById()
.setId("valid_value")
.setMarkTrackingCompletedByIdRequest(request)
.create();
.delete();
System.out.println(response.getData());
```

### /couriers
**GET** /couriers
### /estimated-delivery-date
**POST** /estimated-delivery-date/predict

```java
GetCouriersResponse response = CourierResource.getCouriers()
.fetch();
EstimatedDeliveryDateRequest request = new EstimatedDeliveryDateRequest();
request.setSlug("valid_value");
EstimatedDeliveryDateRequestOriginAddress originAddress = new EstimatedDeliveryDateRequestOriginAddress();
request.setOriginAddress(originAddress);
EstimatedDeliveryDateRequestDestinationAddress destinationAddress = new EstimatedDeliveryDateRequestDestinationAddress();
request.setDestinationAddress(destinationAddress);
PredictResponse response = EstimatedDeliveryDateResource.predict()
.setPredictRequest(request)
.create();
System.out.println(response.getData());
```

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

```java
DetectCourierRequest request = new DetectCourierRequest();
request.setTrackingNumber("valid_value");
DetectCourierResponse response = CourierResource.detectCourier()
.setDetectCourierRequest(request)
PredictBatchRequest request = new PredictBatchRequest();
PredictBatchResponse response = EstimatedDeliveryDateResource.predictBatch()
.setPredictBatchRequest(request)
.create();
System.out.println(response.getData());
```

### /courier-connections
**GET** /courier-connections
### /trackings
**GET** /trackings

```java
GetCourierConnectionsResponse response = CourierConnectionResource.getCourierConnections()
GetTrackingsResponse response = TrackingResource.getTrackings()
.fetch();
System.out.println(response.getData());
```

**POST** /courier-connections
**POST** /trackings

```java
PostCourierConnectionsRequest request = new PostCourierConnectionsRequest();
request.setCourierSlug("valid_value");
request.setCredentials();
PostCourierConnectionsResponse response = CourierConnectionResource.postCourierConnections()
.setPostCourierConnectionsRequest(request)
CreateTrackingRequest request = new CreateTrackingRequest();
request.setTrackingNumber("valid_value");
CreateTrackingResponse response = TrackingResource.createTracking()
.setCreateTrackingRequest(request)
.create();
System.out.println(response.getData());
```

**GET** /courier-connections/{id}
**GET** /trackings/{id}

```java
GetCourierConnectionsByIdResponse response = CourierConnectionResource.getCourierConnectionsById()
GetTrackingByIdResponse response = TrackingResource.getTrackingById()
.setId("valid_value")
.fetch();
System.out.println(response.getData());
```

**PATCH** /courier-connections/{id}
**PUT** /trackings/{id}

```java
PutCourierConnectionsByIdRequest request = new PutCourierConnectionsByIdRequest();
request.setCredentials();
PutCourierConnectionsByIdResponse response = CourierConnectionResource.putCourierConnectionsById()
UpdateTrackingByIdRequest request = new UpdateTrackingByIdRequest();
UpdateTrackingByIdResponse response = TrackingResource.updateTrackingById()
.setId("valid_value")
.setPutCourierConnectionsByIdRequest(request)
.setUpdateTrackingByIdRequest(request)
.update();
System.out.println(response.getData());
```

**DELETE** /courier-connections/{id}
**DELETE** /trackings/{id}

```java
DeleteCourierConnectionsByIdResponse response = CourierConnectionResource.deleteCourierConnectionsById()
DeleteTrackingByIdResponse response = TrackingResource.deleteTrackingById()
.setId("valid_value")
.delete();
System.out.println(response.getData());
```

### /estimated-delivery-date
**POST** /estimated-delivery-date/predict
**POST** /trackings/{id}/retrack

```java
EstimatedDeliveryDateRequest request = new EstimatedDeliveryDateRequest();
request.setSlug("valid_value");
EstimatedDeliveryDateRequestOriginAddress originAddress = new EstimatedDeliveryDateRequestOriginAddress();
request.setOriginAddress(originAddress);
EstimatedDeliveryDateRequestDestinationAddress destinationAddress = new EstimatedDeliveryDateRequestDestinationAddress();
request.setDestinationAddress(destinationAddress);
PredictResponse response = EstimatedDeliveryDateResource.predict()
.setPredictRequest(request)
RetrackTrackingByIdResponse response = TrackingResource.retrackTrackingById()
.setId("valid_value")
.create();
System.out.println(response.getData());
```

**POST** /estimated-delivery-date/predict-batch
**POST** /trackings/{id}/mark-as-completed

```java
PredictBatchRequest request = new PredictBatchRequest();
PredictBatchResponse response = EstimatedDeliveryDateResource.predictBatch()
.setPredictBatchRequest(request)
MarkTrackingCompletedByIdRequest request = new MarkTrackingCompletedByIdRequest();
MarkTrackingCompletedByIdResponse response = TrackingResource.markTrackingCompletedById()
.setId("valid_value")
.setMarkTrackingCompletedByIdRequest(request)
.create();
System.out.println(response.getData());
```
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.aftership</groupId>
<artifactId>tracking-sdk</artifactId>
<version>11.0.0</version>
<version>12.0.0</version>

<name>AfterShip Tracking SDK</name>
<description>The official AfterShip Tracking Java API library</description>
Expand Down
Loading