ekart

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 1, 2026 License: MIT

README

ekart

A production-grade Go client for the Ekart Logistics API.

  • Zero dependencies — standard library only.
  • Automatic auth — bearer tokens are fetched, cached, and refreshed for you.
  • Resilient — transient failures (network errors, HTTP 429/5xx) are retried with exponential backoff and full jitter.
  • Typed — every request and response in the OpenAPI spec is a Go type, and API errors surface as a structured *APIError.
  • Context-aware — every call takes a context.Context for cancellation and deadlines.
  • Tested — the transport, auth caching, retry logic, and every endpoint are covered by httptest-backed tests.

The reference OpenAPI document is vendored at docs/openapi.yaml.

Install

go get github.com/entanglesoftware/ekart/pkg/ekart
import "github.com/entanglesoftware/ekart/pkg/ekart"

Requires Go 1.23 or newer.

Project layout

pkg/ekart/              # the public SDK (import this)
cmd/create-shipment/    # runnable example command
internal/retry/         # private backoff/jitter helpers (not importable)
docs/openapi.yaml       # vendored OpenAPI reference

Quick start

package main

import (
	"context"
	"errors"
	"fmt"
	"log"

	"github.com/entanglesoftware/ekart"
)

func main() {
	client, err := ekart.New(ekart.Config{
		ClientID: "your-client-id",
		Username: "your-username",
		Password: "your-password",
	})
	if err != nil {
		log.Fatal(err)
	}

	ack, err := client.Shipments.Create(context.Background(), &ekart.Shipment{
		SellerName:              "Acme",
		ConsigneeName:           "Asha Rao",
		ConsigneeAlternatePhone: "9876543210",
		OrderNumber:             "ORD-1",
		InvoiceNumber:           "INV-1",
		InvoiceDate:             "2026-08-01",
		ProductsDesc:            "Widgets",
		CategoryOfGoods:         "General",
		PaymentMode:             ekart.PaymentCOD,
		TotalAmount:             999, TaxValue: 152, TaxableAmount: 847,
		CommodityValue: "847", CODAmount: 999, Quantity: 1,
		Weight: 500, Length: 10, Height: 10, Width: 10,
		DropLocation: &ekart.LocationV1{
			Name: "Asha Rao", Phone: 9876543210, Pin: 560025,
			Address: "42 Residency Road", City: "Bengaluru",
			State: "Karnataka", Country: "India",
		},
	})
	if err != nil {
		var apiErr *ekart.APIError
		if errors.As(err, &apiErr) {
			log.Fatalf("ekart rejected the request: %d %s", apiErr.HTTPStatus, apiErr.Message)
		}
		log.Fatal(err)
	}
	fmt.Println("tracking id:", ack.TrackingID)
	fmt.Println("track at:", ack.TrackingURL())
}

A runnable version lives in cmd/create-shipment.

Authentication

ekart.New requires either credentials (ClientID + Username + Password) or a pre-issued Token.

With credentials, the client calls the authorization endpoint on the first protected request, caches the returned token, reuses it until shortly before it expires, and refreshes automatically. Concurrent requests share a single refresh rather than stampeding the auth endpoint. Tokens are never sent to the public tracking endpoints, which are unauthenticated.

// Supply a token you already hold (skips the credential exchange).
client, _ := ekart.New(ekart.Config{Token: "eyJ..."})

// Force a fresh token on the next protected call.
if err := client.ResetToken(ctx); err != nil { /* store error */ }
Token caching

By default the token is cached in memory (NewMemoryTokenStore) and held until the process restarts — no configuration needed. To share the token across processes or restarts, implement the TokenStore interface and pass it in Config:

type TokenStore interface {
	Get(ctx context.Context) (CachedToken, bool, error) // bool=false on a miss
	Set(ctx context.Context, tok CachedToken) error     // empty Value clears
}

client, _ := ekart.New(ekart.Config{
	ClientID: "...", Username: "...", Password: "...",
	TokenStore: myRedisStore{rdb}, // Redis, a file, a bucket — your choice
})

The store is treated as a best-effort cache: a Get error falls through to a fresh fetch and a Set error never fails the request, so a cache outage (e.g. Redis down) degrades to fetching a token per call rather than blocking API traffic. See the TokenStore doc comment for a Redis sketch.

Configuration

Field Default Description
ClientID Client id from Ekart onboarding.
Username Auth username.
Password Auth password.
Token Pre-issued bearer token (skips credential exchange).
BaseURL https://app.elite.ekartlogistics.in API base URL.
HTTPClient &http.Client{Timeout: 30s} Custom HTTP client (proxies, transports, timeouts).
MaxRetries 3 Retries for transient failures. -1 disables retries.
UserAgent ekart-go/<version> Overrides the User-Agent header.
TokenStore in-memory (till restart) Pluggable token cache (Redis / file / bucket).

Services

Service Methods
client.Auth Token
client.Shipments Create, Cancel, SetDispatchDate, UpdateEWBN
client.Label DownloadPDF, DownloadJSON
client.Manifest Download
client.Track ByID (public), Ekart (raw non-large / large)
client.Serviceability V2, V3, Bulk
client.NDR Act
client.Address Add, List
client.Webhook List, Add, Update
client.Estimate Get
Error handling

Non-2xx responses are returned as *ekart.APIError, carrying the HTTP status plus the API's structured code, message, description, and severity:

if apiErr, ok := ekart.AsAPIError(err); ok {
	if apiErr.Temporary() {
		// 429 / 5xx — safe to retry later.
	}
}
Optional fields

Fields the API treats as optional booleans/numbers are pointers so you can distinguish "unset" from a zero value. Use ekart.Ptr to set them:

shipment.DelayedDispatch = ekart.Ptr(true)
webhook.Active = ekart.Ptr(false)

Development

make check      # gofmt + go vet + go test -race
make cover      # coverage summary
make lint       # golangci-lint (if installed)

License

MIT

Directories

Path Synopsis
cmd
create-shipment command
Command create-shipment is a runnable example of the ekart client.
Command create-shipment is a runnable example of the ekart client.
internal
retry
Package retry provides the backoff and context-aware sleep primitives used by the ekart client's transport layer.
Package retry provides the backoff and context-aware sleep primitives used by the ekart client's transport layer.
pkg
ekart
Package ekart is a production-grade Go client for the Ekart Logistics API (https://app.elite.ekartlogistics.in).
Package ekart is a production-grade Go client for the Ekart Logistics API (https://app.elite.ekartlogistics.in).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL