Skip to main content

Official Python SDK for the KiriminAja logistics API

Project description

KiriminAja Python SDK

PyPI version PyPI downloads license

Official Python SDK for the KiriminAja logistics API. Supports both sync and async, and is fully framework-agnostic — works out of the box with the stdlib, or plug in your existing httpx, requests, or aiohttp client.

Requirements

  • Python 3.10+
  • No required runtime dependencies. Install an HTTP client only if you want one (pip install kiriminaja[httpx], [requests], or [aiohttp]).

Installation

pip install kiriminaja
# Optional extras:
pip install "kiriminaja[httpx]"      # for httpx (sync + async)
pip install "kiriminaja[requests]"   # for requests (sync only)
pip install "kiriminaja[aiohttp]"    # for aiohttp (async only)

Quick Start

Create a client with your API key, then call any service method.

from kiriminaja import KiriminAja, Env

client = KiriminAja(
    env=Env.SANDBOX,  # or Env.PRODUCTION
    api_key="YOUR_API_KEY",
)

# Use any service
provinces = client.address.provinces()

Async

from kiriminaja import AsyncKiriminAja, Env

async with AsyncKiriminAja(env=Env.SANDBOX, api_key="YOUR_API_KEY") as client:
    provinces = await client.address.provinces()

Config Options

Option Type Default Description
env Env Env.SANDBOX Target environment
api_key str Your KiriminAja API key
base_url str Derived from env Override the base URL
http_client Any stdlib urllib Custom sync HTTP client (see below)

For AsyncKiriminAja, use async_http_client instead. It defaults to httpx.AsyncClient when httpx is installed; otherwise pass an aiohttp.ClientSession or your own AsyncHttpTransport.

# Custom base URL
client = KiriminAja(
    base_url="https://tdev.kiriminaja.com",
    api_key="YOUR_API_KEY",
)

# Plug in httpx
import httpx
client = KiriminAja(api_key="...", http_client=httpx.Client(timeout=10))

# Plug in requests
import requests
client = KiriminAja(api_key="...", http_client=requests.Session())

# Async with aiohttp
import aiohttp
async with aiohttp.ClientSession() as session:
    client = AsyncKiriminAja(api_key="...", async_http_client=session)
    await client.address.provinces()

Bring your own transport

For frameworks that ship their own HTTP layer (e.g. internal proxies, service meshes, sandboxed environments), implement HttpTransport / AsyncHttpTransport directly:

from kiriminaja import KiriminAja, HttpResponse, HttpTransport

class MyTransport(HttpTransport):
    def request(self, method, url, *, headers, content):
        # …call your own HTTP layer here…
        return HttpResponse(status_code=200, headers={}, content=b'{"status": true}')

client = KiriminAja(api_key="...", http_client=MyTransport())

Services

Address

# List all provinces
client.address.provinces()

# Cities in a province (provinsi_id)
client.address.cities(5)

# Districts in a city (kabupaten_id)
client.address.districts(12)

# Sub-districts in a district (kecamatan_id)
client.address.sub_districts(77)

# Search districts by name
client.address.districts_by_name("jakarta")

Coverage Area & Pricing

from kiriminaja import (
    PricingExpressPayload,
    PricingInstantPayload,
    PricingInstantLocationPayload,
    InstantService,
    InstantVehicle,
)

# Express shipping rates
client.coverage_area.pricing_express(PricingExpressPayload(
    origin=1,
    destination=2,
    weight=1000,  # grams
    item_value=50000,
    insurance=0,
    courier=["jne", "jnt"],
))

# Instant (same-day) rates
client.coverage_area.pricing_instant(PricingInstantPayload(
    service=[InstantService.GOSEND],
    item_price=10000,
    origin=PricingInstantLocationPayload(lat=-6.2, long=106.8, address="Jl. Sudirman No.1"),
    destination=PricingInstantLocationPayload(lat=-6.21, long=106.81, address="Jl. Thamrin No.5"),
    weight=1000,
    vehicle=InstantVehicle.BIKE,
    timezone="Asia/Jakarta",
))

Order — Express

from kiriminaja import (
    RequestPickupItem,
    RequestPickupItemMetadata,
    RequestPickupPackage,
    RequestPickupPayload,
)

# Track by order ID
client.order.express.track("ORDER123")

# Cancel by AWB
client.order.express.cancel("AWB123456", "Customer request")

# Request pickup
client.order.express.request_pickup(RequestPickupPayload(
    address="Jl. Jodipati No.29",
    phone="08133345678",
    name="Tokotries",
    kecamatan_id=548,
    schedule="2021-11-30 22:00:00",
    packages=[
        RequestPickupPackage(
            order_id="YGL-000000019",
            destination_name="Flag Test",
            destination_phone="082223323333",
            destination_address="Jl. Magelang KM 11",
            destination_kecamatan_id=548,
            weight=520,
            width=8,
            length=8,
            height=8,
            item_value=275000,
            shipping_cost=65000,
            service="jne",
            service_type="REG23",
            cod=0,
            package_type_id=7,
            item_name="TEST Item name",
            # `items` is optional. When provided, it lists the individual
            # items inside the package. `item_value` is still required.
            items=[
                RequestPickupItem(
                    name="Kaos Polos",
                    price=125000,
                    qty=2,
                    weight=260,
                    width=4,
                    length=4,
                    height=4,
                    metadata=RequestPickupItemMetadata(
                        sku="KP-001",
                        variant_label="Merah / L",
                    ),
                ),
            ],
        ),
    ],
))

Order — Instant

from kiriminaja import (
    InstantPickupPayload,
    InstantPickupPackage,
    InstantPickupItem,
    InstantService,
    InstantVehicle,
)

# Create instant pickup
client.order.instant.create(InstantPickupPayload(
    service=InstantService.GOSEND,
    service_type="instant",
    vehicle=InstantVehicle.BIKE,
    order_prefix="BDI",
    packages=[
        InstantPickupPackage(
            origin_name="Rizky",
            origin_phone="081280045616",
            origin_lat=-7.854584,
            origin_long=110.331154,
            origin_address="Wirobrajan, Yogyakarta",
            origin_address_note="Dekat Kantor",
            destination_name="Okka",
            destination_phone="081280045616",
            destination_lat=-7.776192,
            destination_long=110.325053,
            destination_address="Godean, Sleman",
            destination_address_note="Dekat Pasar",
            shipping_price=34000,
            item=InstantPickupItem(
                name="Barang 1",
                description="Barang 1 Description",
                price=20000,
                weight=1000,
            ),
        ),
    ],
))

# Find a new driver for an existing order
client.order.instant.find_new_driver("ORDER123")

# Cancel instant order
client.order.instant.cancel("ORDER123")

# Track instant order
client.order.instant.track("ORDER123")

Courier

# List available couriers
client.courier.list()

# Courier groups
client.courier.group()

# Courier service detail
client.courier.detail("jne")

# Set whitelist services
client.courier.set_whitelist_services(["jne_reg", "jne_yes"])

Credit

# Get the current KiriminAja credit balance
client.credit.balance()

AWB (Print Waybill)

# Print shipping label / waybill by AWB number(s)
client.awb.print({"awb": ["AWB123", "AWB456"]})
# response["data"]["data"]["url"] -> PDF download URL

Calculations (COD)

# Calculate COD (Cash on Delivery) fee
client.calculations.cod({
    "item_price": 100000,
    "data": [
        {
            "courier_code": "jne",
            "courier_service_code": "reg",
            "shipping_cost": 10000,
        },
    ],
})
# response["results"] -> list of fee breakdown per courier/service

Profile

# Get member profile and metadata
client.profile.get()
# response["results"]["id"], response["results"]["email"], etc.

Utilities — Volumetric

Estimate the smallest bounding box (length / width / height) for a multi-item package by trying three stacking strategies and returning the arrangement with the smallest volume.

from kiriminaja.utils.volumetric import VolumetricItem, calculate

dim = calculate([
    VolumetricItem(qty=2, length=10, width=10, height=2),
    VolumetricItem(qty=1, length=5,  width=5,  height=5),
])
# dim.length, dim.width, dim.height
# Plain dicts are also accepted: {"qty": 2, "length": 10, ...}

Pickup Schedules

client.pickup.schedules()

Payment

client.payment.get_payment("PAY123")

Contributing

For any requests, bugs, or comments, please open an issue or submit a pull request.

Development

uv sync          # install dependencies
uv run pytest    # run tests
uv run mypy src/ # typecheck

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

kiriminaja-1.0.1.tar.gz (19.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

kiriminaja-1.0.1-py3-none-any.whl (20.4 kB view details)

Uploaded Python 3

File details

Details for the file kiriminaja-1.0.1.tar.gz.

File metadata

  • Download URL: kiriminaja-1.0.1.tar.gz
  • Upload date:
  • Size: 19.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for kiriminaja-1.0.1.tar.gz
Algorithm Hash digest
SHA256 588084aa5f816e9025191bb7eae803b1a057a73ed7d165201a40cd73ae8f9b4d
MD5 43cad94221d4dcfe407c1fba635ee6ad
BLAKE2b-256 1bd6e6c4bcd17185850117379327e79cad55fcff00d0f4cc827a591c6d41ee8d

See more details on using hashes here.

Provenance

The following attestation bundles were made for kiriminaja-1.0.1.tar.gz:

Publisher: release.yml on kiriminaja/python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file kiriminaja-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: kiriminaja-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 20.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for kiriminaja-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 78fbaf8014d9abf79f9455c2c870e048780c09f7b4245338f5ca6b1a3e7dc57f
MD5 9b9dc02690446220fa0ced96d22ae724
BLAKE2b-256 5bf4e4a2167f77a1d53adbcc3500b4ee1f4ccbf6c81f6ac6445bda2c21fa4139

See more details on using hashes here.

Provenance

The following attestation bundles were made for kiriminaja-1.0.1-py3-none-any.whl:

Publisher: release.yml on kiriminaja/python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page