Nhà phát triển
Mobility Hub API
Kết nối CSMS, ứng dụng và phần mềm của bạn với Mobility Hub: đọc trạm, nhận sự kiện qua webhook. Voucher, khách hàng thân thiết và hồ sơ doanh nghiệp sẽ dùng cùng nền tảng này.
curl http://localhost:3000/api/v1/stations?limit=10 \ -H "Authorization: Bearer mh_sk_test_…"
Xác thực
Gửi khóa bí mật trong tiêu đề Authorization: Bearer. Khóa live (mh_sk_live_…) làm việc với dữ liệu thật; khóa test (mh_sk_test_…) với dữ liệu thử, không bao giờ hiện cho người lái. Khóa live tạo được sau khi Mobility Hub xác minh tổ chức. Đừng bao giờ đặt khóa bí mật trong ứng dụng di động hay trang web.
Quyền (scope)
Mỗi khóa chỉ gọi được những thao tác mà quyền của nó cho phép; thiếu quyền, API trả 403 insufficient_scope.
stations:read: Đọc trạm sạcevents:read: Đọc sự kiện
Các thao tác
get /v1/meThe key that made the request, and its organization. Mọi khóa
get /v1/stationsList the organization's stations, by id. Quyền: stations:read
get /v1/stations/{id}Retrieve a station. Quyền: stations:read
get /v1/eventsList the events of the last 30 days, newest first. Quyền: events:read
get /v1/events/{id}Retrieve an event. Quyền: events:read
Phiên bản
Phiên bản API theo ngày (2026-11-01). Tổ chức được gắn phiên bản mới nhất khi tạo khóa đầu tiên; gửi tiêu đề MH-Version để chọn một phiên bản khác. Trong cùng một phiên bản, Mobility Hub chỉ thêm, không đổi hay bỏ.
Lỗi
Mọi lỗi trả về dạng application/problem+json (RFC 9457) với code ổn định để lập trình theo, và request_id để báo cho Mobility Hub.
| Mã | Ý nghĩa |
|---|---|
| authentication_required | Thiếu khóa, hoặc khóa sai, đã thu hồi hay hết hạn (401). |
| permission_denied | Tổ chức không dùng được API ở chế độ này (403). |
| insufficient_scope | Khóa thiếu quyền cho thao tác (403). |
| resource_missing | Không tìm thấy, hoặc thuộc tổ chức hay chế độ khác (404). |
| invalid_request | Tham số hoặc MH-Version không hợp lệ (400). |
| rate_limited | Quá giới hạn tần suất, đợi Retry-After giây (429). |
| internal_error | Lỗi phía Mobility Hub; báo kèm request_id (500). |
Giới hạn tần suất
Mỗi khóa live gửi tối đa 200 yêu cầu mỗi 10 giây, khóa test 50. Tiêu đề RateLimit cho biết còn bao nhiêu; quá giới hạn, API trả 429 kèm Retry-After.
Phân trang
Danh sách trả về object: "list", data và has_more. Lấy trang sau bằng starting_after = id cuối cùng của trang trước; limit từ 1 đến 100.
Webhook
Mỗi lần gửi là một sự kiện JSON với ba tiêu đề webhook-id, webhook-timestamp, webhook-signature theo chuẩn Standard Webhooks. Trả 2xx trong 10 giây; nếu không, Mobility Hub gửi lại với khoảng cách tăng dần trong khoảng ba ngày. Trả 410 để Mobility Hub tắt địa chỉ. Sự kiện có thể đến không theo thứ tự và có thể lặp: dùng webhook-id để bỏ qua bản trùng.
Các loại sự kiện
station.created: Trạm được thêmstation.updated: Trạm được sửastation.removed: Trạm bị gỡ
Xác minh chữ ký (Node.js)
import { createHmac, timingSafeEqual } from "node:crypto";
// body: the raw request body, as received, before any JSON parsing.
export function verifyWebhook(secret, headers, body) {
const id = headers["webhook-id"];
const timestamp = Number(headers["webhook-timestamp"]);
if (!id || Math.abs(Date.now() / 1000 - timestamp) > 300) return false;
const key = Buffer.from(secret.slice("whsec_".length), "base64");
const expected = createHmac("sha256", key).update(`${id}.${timestamp}.${body}`).digest();
return String(headers["webhook-signature"] ?? "").split(" ").some((part) => {
const [version, signature] = part.split(",");
const given = Buffer.from(signature ?? "", "base64");
return version === "v1" && given.length === expected.length && timingSafeEqual(given, expected);
});
}