This version of the SDK has been deprecated and replaced with the newly reconstructed SDK.
For the latest API features and improved integration, please visit our updated repository at https://github.com/AfterShip/tracking-sdk-go and follow the provided instructions.
AfterShip provides an API to Track & Notify of shipments from hundreds of couriers worldwide. aftership-sdk-go is a SDK to develop Apps using AfterShip API 2023-10 in golang. All endpoints including couriers, tracking, last checkpoint and notification are supported.
You will need to create an account at AfterShip and obtain an API key first to access AfterShip APIs using aftership-go SDK.
aftership-sdk-go requires a Go version with Modules support and uses import versioning. So please make sure to initialize a Go module before installing aftership-sdk-go:
go mod init github.com/my/repo
go get github.com/aftership/aftership-sdk-go/v3
Import:
import "github.com/aftership/aftership-sdk-go/v3"
package main
import (
"context"
"fmt"
"github.com/aftership/aftership-sdk-go/v3"
)
func main() {
client, err := aftership.NewClient(aftership.Config{
APIKey: "YOUR_API_KEY",
})
if err != nil {
fmt.Println(err)
return
}
// Get couriers
result, err := client.GetCouriers(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result)
}
make test
Create AfterShip SDK instance with config
config
- object of request configAPIKey
- Required, AfterShip API keyAuthenticationType
-APIKey
/AES
APISecret
- if AuthenticationType is AES, use aes api secretEndpoint
- string, AfterShip endpoint, default 'https://api.aftership.com/tracking/2023-10'UserAagentPrefix
- string, prefix of User-Agent in headers, default "aftership-sdk-go"
Example:
AuthenticationType APIKey
client, err := aftership.NewClient(aftership.Config{
APIKey: "YOUR_API_KEY",
UserAagentPrefix: "aftership-sdk-go",
})
AuthenticationType AES
signature
client, err := aftership.NewClient(aftership.Config{
APIKey: "YOUR_API_KEY",
AuthenticationType: aftership.AES,
APISecret: "YOUR_API_SECRET",
})
To understand AfterShip rate limit policy, please see Limit
section in https://www.aftership.com/docs/tracking/quickstart/rate-limit
You can get the recent rate limit by client.GetRateLimit()
. Initially all value are 0
.
import (
"context"
"fmt"
"github.com/aftership/aftership-sdk-go/v3"
)
func main() {
client, err := aftership.NewClient(aftership.Config{
APIKey: "YOUR_API_KEY",
})
if err != nil {
fmt.Println(err)
return
}
fmt.Println(client.GetRateLimit())
// terminal output
/*
{
"reset": 0,
"limit": 0,
"remaining": 0,
}
*/
// Get couriers
result, err := client.GetCouriers(context.Background())
if err != nil {
fmt.Println(err)
} else {
fmt.Println(result)
}
// Rate Limit
fmt.Println(client.GetRateLimit())
// terminal output
/*
{
"reset": 1588249242,
"limit": 10,
"remaining": 9,
}
*/
}
In case you exceeded the rate limit, you will receive the 429 Too Many Requests
error with the following error message:
{
"code": 429,
"type": "TooManyRequests",
"message": "You have exceeded the API call rate limit. Default limit is 10 requests per second.",
"path": "/couriers",
"rate_limit": {
"rest": 1458463600,
"limit": 10,
"remaining": 0
}
}
There are 3 kinds of error
- SDK Error
- Request Error
- API Error
Throw by the new SDK client
client, err := aftership.NewClient(aftership.Config{
APIKey: "",
})
if err != nil {
fmt.Println(err)
return
}
/*
invalid credentials: API Key must not be empty
*/
Throw by the parameter validation in function
client, err := aftership.NewClient(aftership.Config{
APIKey: "YOUR_API_KEY",
})
// Get notification
param := aftership.SlugTrackingNumber{
Slug: "dhl",
}
result, err := client.GetNotification(context.Background(), param)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result)
/*
slug or tracking number is empty, both of them must be provided
*/
client, err := aftership.NewClient(aftership.Config{
APIKey: "YOUR_API_KEY",
})
// Get couriers
result, err := client.GetCouriers(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result)
/*
HTTP request failed: Get https://api.aftership.com/v4/couriers: dial tcp: lookup api.aftership.com: no such host
*/
Error return by the AfterShip API https://www.aftership.com/docs/tracking/quickstart/request-errors
API Error struct of this SDK contain fields:
Code
- error code for API ErrorType
- type of the errorMessage
- detail message of the errorPath
- URI path when making requestRateLimit
- Optional - When the API gets429 Too Many Requests
error, the error struct will return theRateLimit
information as well.
client, err := aftership.NewClient(aftership.Config{
APIKey: "INVALID_API_KEY",
})
// Get couriers
result, err := client.GetCouriers(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result)
/*
{
"code": 401,
"type": "Unauthorized",
"message": "Invalid API key.",
"path": "/couriers"
}
*/
Get a list of our supported couriers.
GET /couriers
Return a list of couriers activated at your AfterShip account.
result, err := client.GetCouriers(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result)
GET /couriers/all
Return a list of all couriers.
result, err := client.GetAllCouriers(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result)
POST /couriers/detect
Return a list of matched couriers based on tracking number format and selected couriers or a list of couriers.
params := aftership.CourierDetectionParams{
TrackingNumber: "906587618687",
}
result, err := client.DetectCouriers(context.Background(), params)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result)
Create trackings, update trackings, and get tracking results.
POST /trackings
Create a tracking.
newTracking := aftership.CreateTrackingParams{
TrackingNumber: "1234567890",
Slug: "dhl",
Title: "Title Name",
SMSes: []string{
"+18555072509",
"+18555072501",
},
Emails: []string{
"email@yourdomain.com",
"another_email@yourdomain.com",
},
OrderID: "ID 1234",
CustomFields: map[string]string{
"product_name": "iPhone Case",
"product_price": "USD19.99",
},
Language: "en",
OrderPromisedDeliveryDate: "2019-05-20",
DeliveryType: "pickup_at_store",
PickupLocation: "Flagship Store",
PickupNote: "Reach out to our staffs when you arrive our stores for shipment pickup",
}
result, err := client.CreateTracking(context.Background(), newTracking)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result)
DELETE /trackings/:slug/:tracking_number
Delete a tracking.
param := aftership.SlugTrackingNumber{
Slug: "dhl",
TrackingNumber: "1234567890",
}
result, err := client.DeleteTracking(context.Background(), param)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result)
GET /trackings
Get tracking results of multiple trackings.
multiParams := aftership.GetTrackingsParams{
Page: 1,
Limit: 10,
}
result, err := client.GetTrackings(context.Background(), multiParams)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result)
GET /trackings/:slug/:tracking_number
Get tracking results of a single tracking.
param := aftership.SlugTrackingNumber{
Slug: "dhl",
TrackingNumber: "1588226550",
}
result, err := client.GetTracking(context.Background(), param, aftership.GetTrackingParams{})
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result)
Pro Tip: You can always use /:id to replace /:slug/:tracking_number.
// GET /trackings/:id
var id TrackingID = "5b7658cec7c33c0e007de3c5"
result, err := client.GetTracking(context.Background(), id, aftership.GetTrackingParams{})
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result)
PUT /trackings/:slug/:tracking_number
Update a tracking.
param := aftership.SlugTrackingNumber{
Slug: "dhl",
TrackingNumber: "1588226550",
}
updateReq := aftership.UpdateTrackingParams{
Title: "New Title",
}
result, err := client.UpdateTracking(context.Background(), param, updateReq)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result)
POST /trackings/:slug/:tracking_number/retrack
Retrack an expired tracking. Max 3 times per tracking.
param := aftership.SlugTrackingNumber{
Slug: "dhl",
TrackingNumber: "1588226550",
}
result, err := client.RetrackTracking(context.Background(), param)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result)
POST /trackings/:slug/:tracking_number/mark-as-completed
Mark a tracking as completed. The tracking won't auto update until retrack it.
param := aftership.SlugTrackingNumber{
Slug: "dhl",
TrackingNumber: "1588226550",
}
result, err := client.MarkTrackingAsCompleted(context.Background(), param, aftership.TrackingCompletedStatusDelivered)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result)
Get tracking information of the last checkpoint of a tracking.
GET /last_checkpoint/:slug/:tracking_number
Return the tracking information of the last checkpoint of a single tracking.
param := aftership.SlugTrackingNumber{
Slug: "ups",
TrackingNumber: "1234567890",
}
result, err := client.GetLastCheckpoint(context.Background(), param, aftership.GetCheckpointParams{})
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result)
Get, add or remove contacts (sms or email) to be notified when the status of a tracking has changed.
GET /notifications/:slug/:tracking_number
Get contact information for the users to notify when the tracking changes.
param := aftership.SlugTrackingNumber{
Slug: "dhl",
TrackingNumber: "1588226550",
}
result, err := client.GetNotification(context.Background(), param)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result)
POST /notifications/:slug/:tracking_number/add
Add notification receivers to a tracking number.
param := aftership.SlugTrackingNumber{
Slug: "dhl",
TrackingNumber: "1588226550",
}
data := notification.Data{
Notification: notification.Notification{
Emails: []string{"user1@gmail.com", "user2@gmail.com", "invalid EMail @ Gmail. com"},
Smses: []string{"+85291239123", "+85261236123", "Invalid Mobile Phone Number"},
},
}
result, err := client.AddNotification(context.Background(), param, data)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result)
POST /notifications/:slug/:tracking_number/remove
Remove notification receivers from a tracking number.
param := aftership.SlugTrackingNumber{
Slug: "dhl",
TrackingNumber: "1588226550",
}
data := notification.Data{
Notification: notification.Notification{
Emails: []string{"user1@gmail.com"},
Smses: []string{"+85291239123"},
},
}
result, err := client.RemoveNotification(context.Background(), param, data)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(result)
Checkpoint.Coordinates
change type from[]string
into[]float32
Tracking
struct add fields- remove
android
field fromTracking
struct
If you get stuck, we're here to help. The following are the best ways to get assistance working through your issue:
- Issue Tracker for questions, feature requests, bug reports and general discussion related to this package. Try searching before you create a new issue.
- Slack AfterShip SDKs: a Slack community, you can find the maintainers and users of this package in #aftership-sdks.
- Email us in AfterShip support:
support@aftership.com
For details on contributing to this repository, see the contributing guide.