API AiAkaun
REST di atas HTTPS, JSON masuk dan keluar, disahkan dengan Bearer token. Setiap endpoint di sini menjalankan enjin perakaunan yang sama seperti papan pemuka — apa yang anda tulis melalui API muncul dalam lejar, laporan dan cukai anda serta-merta. Versi ialah kontrak: v1 kekal berfungsi apabila v2 tiba.
Pengesahan
Setiap permintaan membawa token API dalam header Authorization. Tiada kunci dalam rentetan pertanyaan, tiada cookie, tiada sesi.
curl https://aiakaun.com/api/v1/me \ -H "Authorization: Bearer $AIAKAUN_TOKEN" \ -H "Accept: application/json"
Mencipta token
Token dijana dalam papan pemuka anda — kami tidak boleh menciptanya untuk anda, dan tiada endpoint API yang mencipta token lain.
- Pergi ke Akaun → API & Webhook.
- Pilih syarikat, namakan token, dan tandakan hanya skop yang integrasi anda benar-benar perlukan.
- Pilihan: hadkan token kepada senarai alamat IP, dan tetapkan tarikh tamat tempoh.
- Salin token mentah SEKARANG. Ia ditunjukkan sekali sahaja — kami menyimpan cincangannya, bukan token itu sendiri, jadi kami tidak boleh menunjukkannya semula.
Satu token, satu syarikat.
Token terikat kepada syarikat tunggal yang anda pilih semasa menciptanya. Tiada parameter untuk menukarnya, dan tiada endpoint yang memulangkan data syarikat lain. Jika anda mengendalikan tiga syarikat, anda memegang tiga token — supaya kunci yang bocor menjejaskan satu set buku, bukan ketiga-tiganya.
Kebenaran berkesan ialah persilangan.
Token tidak boleh memberi pemiliknya akses yang mereka sendiri tidak ada. Setiap permintaan menyemak DUA perkara: skop yang token pegang, dan kebenaran syarikat yang manusia itu masih pegang hari ini. Turunkan pangkat akauntan kepada baca-sahaja dan token yang mereka jana semalam berhenti menulis serta-merta.
Skop
Skop menjawab "apa yang KUNCI ini boleh buat?". Kebenaran syarikat menjawab "apa yang MANUSIA ini boleh buat?". Kedua-duanya mesti membenarkan permintaan itu. Lajur ketiga di bawah menunjukkan kebenaran yang pemilik token juga mesti pegang.
Syarikat
| Skop | Membenarkan | Kebenaran syarikat |
|---|---|---|
| read:company | Baca maklumat syarikat | dashboard.view |
Perakaunan
| Skop | Membenarkan | Kebenaran syarikat |
|---|---|---|
| read:accounts | Baca carta akaun | accounts.view |
| read:transactions | Baca transaksi | transactions.view |
| read:invoices | Baca invois | invoices.view |
| read:bills | Baca bil pembelian | bills.view |
| read:contacts | Baca pelanggan & pembekal | contacts.view |
| write:transactions | Cipta & sunting transaksi | transactions.create |
| write:invoices | Cipta & sunting invois | invoices.create |
| write:bills | Cipta bil pembelian | bills.create |
| write:contacts | Cipta & sunting kontak | contacts.create |
Operasi
| Skop | Membenarkan | Kebenaran syarikat |
|---|---|---|
| read:products | Baca inventori | products.view |
| write:products | Cipta & sunting inventori | products.create |
Dokumen
| Skop | Membenarkan | Kebenaran syarikat |
|---|---|---|
| read:documents | Baca dokumen dimuat naik | documents.view |
| write:documents | Muat naik dokumen untuk AI | documents.create |
Laporan
| Skop | Membenarkan | Kebenaran syarikat |
|---|---|---|
| read:reports | Baca laporan kewangan | reports.view |
Minta skop yang paling sedikit yang masih menyiapkan kerja. Skrip yang hanya menyegerakkan invois ke papan pemuka anda tidak memerlukan write:transactions — dan token baca-sahaja yang bocor ialah insiden, bukan bencana.
Had kadar
Had dikira setiap TOKEN, bukan setiap alamat IP. Beberapa pelanggan berkongsi satu IP pejabat, dan satu skrip yang berjalan liar tidak sepatutnya menyekat semua orang di belakang router yang sama.
| Had | Kadar | Kod apabila dilanggar |
|---|---|---|
| Semua permintaan API | 120 / minit | rate_limited HTTP 429 |
| Muat naik dokumen POST /api/v1/documents | 10 / minit | upload_rate_limited HTTP 429 |
Muat naik jauh lebih ketat kerana setiap satu menelan token AI sebenar — gelung yang tidak terkawal menelan belanja, bukan hanya CPU. Had muat naik dikira SEBAGAI TAMBAHAN kepada had 120/minit.
Header dan cara mengendalikan 429
X-RateLimit-Limit— bilangan permintaan yang dibenarkan dalam tetingkap semasa.X-RateLimit-Remaining— baki dalam tetingkap itu. Perlahankan apabila ia menghampiri sifar.Retry-After— hanya pada 429: saat sehingga anda boleh cuba lagi. HORMATI nilai ini; jangan cuba semula dengan segera dalam gelung ketat.
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 0
Retry-After: 37
Content-Type: application/json
{
"error": {
"code": "rate_limited",
"message": "Terlalu banyak permintaan. Cuba lagi sebentar."
}
}
Bentuk respons
Tiga bentuk sahaja, sama di setiap endpoint. Data sentiasa berada di bawah kunci data; ralat sentiasa di bawah kunci error. Anda tidak perlu menghurai bentuk kesepuluh setiap kali kami menambah endpoint.
Satu rekod
{
"data": {
"id": 1234,
"date": "2026-08-01",
"description": "Bayaran pelanggan — invois INV-0091",
"amount": 1250.00,
"type": "income",
"status": "confirmed",
"created_at": "2026-08-01T09:14:22+08:00"
}
}
Koleksi bernombor halaman
Kawal saiz halaman dengan per_page (lalai 50, maksimum 200) dan halaman dengan page. Ikut links.next sehingga ia null — jangan kira halaman sendiri.
{
"data": [
{ "id": 1234, "date": "2026-08-01", "amount": 1250.00, "type": "income" },
{ "id": 1235, "date": "2026-08-02", "amount": 1800.00, "type": "expense" }
],
"meta": {
"current_page": 1,
"per_page": 50,
"total": 312,
"last_page": 7
},
"links": {
"next": "https://aiakaun.com/api/v1/transactions?page=2",
"prev": null
}
}
Ralat
{
"error": {
"code": "validation_failed",
"message": "Data yang dihantar tidak lengkap.",
"fields": {
"amount": ["Medan amount diperlukan."],
"date": ["Medan date bukan tarikh yang sah."]
}
}
}
Jenis medan
- Wang — nombor perpuluhan dua tempat dalam mata wang syarikat, cth 1250.00. BUKAN sen. Kami menyimpan sen secara dalaman; menyalahtafsirkannya ialah cara paling senyap untuk merosakkan buku seseorang.
- Cap masa — ISO-8601 dengan offset, cth 2026-08-01T09:14:22+08:00.
- Tarikh — Y-m-d tanpa masa untuk medan yang memang tarikh, cth tarikh transaksi.
- Padam — memulangkan 204 tanpa badan.
Kod ralat
Kod bersifat stabil dan boleh dibaca mesin — buat cabang keputusan anda terhadap error.code, bukan terhadap teks mesej, yang boleh berubah dan diterjemah.
| Kod | HTTP | Maksudnya |
|---|---|---|
| validation_failed | 422 | Badan permintaan gagal pengesahan. Objek fields menyenaraikan setiap medan yang bermasalah. |
| not_found | 404 | Rekod tidak wujud — atau ia wujud tetapi bukan milik syarikat token ini. Kami sengaja tidak membezakan keduanya. |
| unauthenticated | 401 | Tiada header Authorization, atau token tidak dikenali atau sudah tamat tempoh. |
| token_revoked | 401 | Token ini dibatalkan dalam papan pemuka. Cipta yang baharu. |
| insufficient_scope | 403 | Token sah tetapi tidak memegang skop yang laluan ini perlukan. Medan required_scope memberitahu yang mana. |
| insufficient_permission | 403 | Token memegang skop, tetapi MANUSIA yang memiliki token itu tidak lagi memegang kebenaran syarikat yang sepadan. |
| account_suspended | 403 | Akaun pemilik token digantung. Semua permintaan berhenti sehingga ia dipulihkan. |
| company_access_revoked | 403 | Pemilik token bukan lagi ahli syarikat itu. Token kekal sah tetapi tidak berguna. |
| company_required | 403 | Token tidak terikat kepada mana-mana syarikat — syarikatnya mungkin telah dipadam. |
| subscription_locked | 402 | Langganan syarikat tidak aktif. GET terus berfungsi; setiap POST, PATCH dan DELETE ditolak sehingga dibaharui. |
| ip_not_allowed | 403 | Permintaan datang dari IP yang tiada dalam senarai putih token. |
| rate_limited | 429 | Melebihi 120 permintaan seminit. Lihat header Retry-After. |
| upload_rate_limited | 429 | Melebihi 10 muat naik dokumen seminit. |
| period_locked | 409 | Tempoh perakaunan sudah ditutup. Transaksi bertarikh dalam tempoh itu tidak boleh dicipta atau diubah. |
402 subscription_locked hanya menjejaskan tulisan. GET terus berfungsi walaupun langganan tamat — anda tidak akan kehilangan akses baca kepada buku anda sendiri kerana kad terlepas pandang.
Rujukan endpoint
Senarai ini dijana daripada jadual laluan hidup pada setiap muatan halaman. Ia tidak boleh lari daripada API sebenar — jika satu endpoint muncul di sini, ia wujud.
Lajur skop menyenaraikan SETIAP skop yang laluan itu perlukan. Apabila dua tersenarai, token anda memerlukan kedua-duanya.
Akaun & token
| Kaedah | Laluan | Skop | Penerangan |
|---|---|---|---|
| GET | /api/v1/me | tiada | Siapa token ini, syarikat mana, dan skop apa yang dipegangnya. |
Syarikat
| Kaedah | Laluan | Skop | Penerangan |
|---|---|---|---|
| GET | /api/v1/company | read:company | Butiran syarikat: nama, jenis, mata wang, bulan akhir tahun kewangan. |
| GET | /api/v1/company/accounts | read:company read:accounts | Carta akaun penuh syarikat. |
Transaksi
| Kaedah | Laluan | Skop | Penerangan |
|---|---|---|---|
| GET | /api/v1/transactions | read:transactions | Senaraikan transaksi. Tapis mengikut julat tarikh, akaun dan status. |
| GET | /api/v1/transactions/{transaction} | read:transactions | Satu transaksi dengan barisan jurnalnya. |
| POST | /api/v1/transactions | write:transactions | Cipta transaksi baharu. |
| PATCH | /api/v1/transactions/{transaction} | write:transactions | Kemas kini transaksi sedia ada. |
| POST | /api/v1/transactions/{transaction}/confirm | write:transactions | Sahkan transaksi cadangan AI supaya ia masuk ke lejar. |
| DELETE | /api/v1/transactions/{transaction} | write:transactions | Padam transaksi. |
Pelanggan & pembekal
| Kaedah | Laluan | Skop | Penerangan |
|---|---|---|---|
| GET | /api/v1/contacts | read:contacts | Senaraikan pelanggan dan pembekal. |
| GET | /api/v1/contacts/{contact} | read:contacts | Satu kontak. |
| POST | /api/v1/contacts | write:contacts | Cipta kontak baharu. |
| PATCH | /api/v1/contacts/{contact} | write:contacts | Kemas kini kontak. |
| DELETE | /api/v1/contacts/{contact} | write:contacts | Padam kontak. |
Invois
| Kaedah | Laluan | Skop | Penerangan |
|---|---|---|---|
| GET | /api/v1/invoices | read:invoices | Senaraikan invois. Tapis mengikut status dan pelanggan. |
| GET | /api/v1/invoices/{invoice} | read:invoices | Satu invois dengan baris itemnya. |
| GET | /api/v1/invoices/{invoice}/pdf | read:invoices | Muat turun PDF invois. |
| POST | /api/v1/invoices | write:invoices | Cipta invois baharu berserta barisnya. |
| PATCH | /api/v1/invoices/{invoice} | write:invoices | Kemas kini invois. |
| POST | /api/v1/invoices/{invoice}/status | write:invoices | Tukar status invois (cth. tandakan dibayar). |
| DELETE | /api/v1/invoices/{invoice} | write:invoices | Padam invois. |
Bil pembelian
| Kaedah | Laluan | Skop | Penerangan |
|---|---|---|---|
| GET | /api/v1/bills | read:bills | Senaraikan bil pembelian. |
| GET | /api/v1/bills/{bill} | read:bills | Satu bil pembelian. |
| POST | /api/v1/bills | write:bills | Cipta bil pembelian. |
Inventori
| Kaedah | Laluan | Skop | Penerangan |
|---|---|---|---|
| GET | /api/v1/products | read:products | Senaraikan item inventori. |
| GET | /api/v1/products/{product} | read:products | Satu item inventori. |
| POST | /api/v1/products | write:products | Cipta item inventori. |
| PATCH | /api/v1/products/{product} | write:products | Kemas kini item inventori. |
Dokumen
| Kaedah | Laluan | Skop | Penerangan |
|---|---|---|---|
| GET | /api/v1/documents | read:documents | Senaraikan dokumen yang dimuat naik dan status pembacaan AI. |
| GET | /api/v1/documents/{document} | read:documents | Satu dokumen dengan hasil ekstrak AI. |
| POST | /api/v1/documents 10/min | write:documents | Muat naik resit atau penyata untuk dibaca AI (multipart/form-data). |
Laporan kewangan
| Kaedah | Laluan | Skop | Penerangan |
|---|---|---|---|
| GET | /api/v1/reports/profit-loss | read:reports | Untung rugi bagi satu tempoh. |
| GET | /api/v1/reports/balance-sheet | read:reports | Kunci kira-kira pada satu tarikh. |
| GET | /api/v1/reports/trial-balance | read:reports | Imbangan duga bagi satu tempoh. |
| GET | /api/v1/reports/aging | read:reports | Penuaan penghutang dan pemiutang. |
Webhook
| Kaedah | Laluan | Skop | Penerangan |
|---|---|---|---|
| GET | /api/v1/webhooks | read:company | Senaraikan endpoint webhook syarikat ini. |
| GET | /api/v1/webhooks/{endpoint}/deliveries | read:company | Log penghantaran bagi satu endpoint. |
Contoh: apa yang /me pulangkan
/me tidak memerlukan sebarang skop dengan sengaja. Ia memberitahu pemanggil siapa mereka, syarikat mana yang token ini pegang, dan skop apa yang ia bawa — mustahil untuk menyahpepijat integrasi tanpanya.
{
"data": {
"user": { "id": 7, "name": "Ali bin Ahmad", "email": "ali@contoh.com" },
"company": { "id": 42, "name": "Perniagaan Ali Sdn Bhd", "currency": "MYR" },
"token": {
"name": "Integrasi kedai",
"last_four": "f3a9",
"read_only": false,
"scopes": ["read:transactions", "write:transactions", "read:reports"],
"expires_at": null
}
}
}
Webhook
Daripada meninjau API kami setiap minit, daftarkan satu URL dan kami akan menolak peristiwa kepada anda apabila ia berlaku. Tambah endpoint dalam Akaun → API & Webhook, pilih peristiwa yang anda mahu, dan simpan rahsia penandatanganan (bermula dengan whsec_) yang kami tunjukkan.
Peristiwa
Nama peristiwa ialah kontrak awam: setelah anda menulis kod terhadap invoice.paid, nama itu tidak akan berubah. Peristiwa baharu ditambah; yang lama tidak dinamakan semula. Anda juga boleh melanggan satu kumpulan penuh dengan kad bebas, cth invoice.*, atau semuanya dengan *.
| Kumpulan | Peristiwa | Dihantar apabila |
|---|---|---|
| transaction.* | transaction.created | Transaksi dicipta |
| transaction.updated | Transaksi dikemas kini | |
| transaction.confirmed | Transaksi disahkan | |
| transaction.deleted | Transaksi dipadam | |
| invoice.* | invoice.created | Invois dicipta |
| invoice.updated | Invois dikemas kini | |
| invoice.paid | Invois dibayar | |
| invoice.deleted | Invois dipadam | |
| bill.* | bill.created | Bil pembelian dicipta |
| bill.paid | Bil pembelian dibayar | |
| contact.* | contact.created | Kontak dicipta |
| contact.updated | Kontak dikemas kini | |
| document.* | document.uploaded | Dokumen dimuat naik |
| document.processed | AI selesai baca dokumen | |
| document.failed | AI gagal baca dokumen | |
| subscription.* | subscription.renewed | Langganan dibaharui |
| subscription.expiring | Langganan hampir tamat | |
| subscription.expired | Langganan tamat tempoh | |
| payment.* | payment.succeeded | Bayaran berjaya |
| payment.refunded | Bayaran dibayar balik |
Muatan
Setiap penghantaran ialah POST JSON dengan sampul yang sama. Kunci data berbeza mengikut peristiwa; semua yang lain kekal.
{
"id": "evt_01k2m9c7q4xz8b3vd6ntr5phaj",
"event": "invoice.paid",
"created_at": "2026-08-07T14:22:05+08:00",
"company": {
"id": 42,
"name": "Perniagaan Ali Sdn Bhd"
},
"data": {
"id": 91,
"number": "INV-0091",
"contact": { "id": 12, "name": "Kedai Runcit Maju" },
"total": 1250.00,
"paid_at": "2026-08-07T14:22:04+08:00",
"status": "paid"
}
}
Header yang kami hantar
| Header | Kandungan |
|---|---|
| X-AiAkaun-Event | Nama peristiwa, cth invoice.paid. Guna ini untuk menghalakan sebelum menghurai badan. |
| X-AiAkaun-Event-Id | Id peristiwa yang stabil (evt_…). SAMA merentas setiap cubaan semula — inilah kunci nyahduplikasi anda. |
| X-AiAkaun-Delivery | Id baris penghantaran. Berbeza bagi setiap endpoint; berguna apabila melaporkan masalah kepada kami. |
| X-AiAkaun-Timestamp | Saat Unix ketika kami menandatangani. Ia SEBAHAGIAN daripada tandatangan — anda mesti memasukkannya semasa mengira semula. |
| X-AiAkaun-Signature | HMAC-SHA256 heksadesimal bagi "cap masa.badan mentah", dikunci dengan rahsia endpoint anda. |
| User-Agent | AiAkaun-Webhooks/1.0 |
Cuba semula
Mana-mana respons 2xx dikira berjaya — 204 sesuai sempurna. Apa-apa yang lain, atau tamat masa, mencetuskan cubaan semula mengikut jadual mundur ini:
| Cubaan | Selepas kegagalan sebelumnya |
|---|---|
| Cuba semula 1 | +30 saat |
| Cuba semula 2 | +2 minit |
| Cuba semula 3 | +10 minit |
| Cuba semula 4 | +1 jam |
| Cuba semula 5 | +6 jam |
Selepas cubaan semula terakhir habis, penghantaran itu ditandakan gagal dan berhenti. Setiap cubaan — kod status dan badan respons anda yang sebenar — kelihatan dalam log penghantaran endpoint anda, jadi "kami tidak pernah terima peristiwa itu" sentiasa ada jawapan.
Pemutus litar
Selepas 15 kegagalan BERTURUT-TURUT, kami mematikan endpoint itu secara automatik dan berhenti menghantar kepadanya. Satu penghantaran yang berjaya mengosongkan kiraan. Hidupkan semula endpoint dalam papan pemuka selepas anda membaiki penerima anda.
Balas dahulu, kerja kemudian.
Kami menunggu 20 saat untuk respons. Sahkan tandatangan, baris-gilirkan kerja, dan balas 2xx dengan segera. Penerima yang melakukan kerja berat secara sebaris akan tamat masa, dicuba semula, dan akhirnya dimatikan — walaupun ia sebenarnya memproses setiap peristiwa dengan betul.
Mengesahkan tandatangan
Sesiapa sahaja boleh POST ke URL webhook anda. Tandatangan itulah yang membezakan kami daripada mereka — sahkannya pada setiap permintaan, sebelum anda mempercayai satu bait pun daripada muatan.
Algoritmanya, tepat:
- Ambil badan permintaan MENTAH — bait sebelum sebarang penghurai JSON menyentuhnya.
- Bina rentetan yang ditandatangani: cap masa, satu titik, kemudian badan mentah.
- Kira HMAC-SHA256 ke atasnya, dikunci dengan rahsia endpoint anda. Bandingkan sebagai heksadesimal huruf kecil.
- Tolak jika cap masa lebih daripada 300 saat dari waktu jam anda. Itulah yang menghentikan muatan lama yang ditangkap daripada dimainkan semula terhadap anda.
- Bandingkan dengan perbandingan masa-tetap (hash_equals / timingSafeEqual / compare_digest) — bukan ==.
Kesilapan yang paling kerap: menandatangani badan yang telah dihurai-dan-dikodkan-semula. Susunan kunci dan jarak akan berbeza sedikit, tandatangan tidak akan sepadan, dan anda akan menghabiskan satu petang menyalahkan kunci anda. Simpan bait mentah.
PHP
<?php
// Sahkan webhook AiAkaun — algoritma yang SAMA seperti pelayan kami.
// Tandatangan meliputi "{timestamp}.{badan mentah}", bukan badan sahaja.
$secret = getenv('AIAKAUN_WEBHOOK_SECRET');
$payload = file_get_contents('php://input'); // badan MENTAH — jangan hurai dahulu
$signature = $_SERVER['HTTP_X_AIAKAUN_SIGNATURE'] ?? '';
$timestamp = (int) ($_SERVER['HTTP_X_AIAKAUN_TIMESTAMP'] ?? 0);
$tolerance = 300; // saat; menolak main semula
if (abs(time() - $timestamp) > $tolerance) {
http_response_code(400);
exit('cap masa di luar toleransi');
}
$expected = hash_hmac('sha256', $timestamp . '.' . $payload, $secret);
// hash_equals, bukan ===. Perbandingan masa-tetap.
if (! hash_equals($expected, $signature)) {
http_response_code(400);
exit('tandatangan tidak sah');
}
$event = json_decode($payload, true);
// Nyahduplikasi guna $event['id'] — cubaan semula menghantar id yang sama.
// Balas 2xx dengan CEPAT; buat kerja berat dalam baris gilir anda sendiri.
http_response_code(204);
Node.js
const crypto = require('crypto');
const express = require('express');
const app = express();
// express.raw, BUKAN express.json — kami menandatangani bait mentah, dan
// penghurai JSON memusnahkannya sebelum anda sempat menyemak.
app.post('/webhook/aiakaun', express.raw({ type: 'application/json' }), (req, res) => {
const secret = process.env.AIAKAUN_WEBHOOK_SECRET;
const payload = req.body.toString('utf8');
const signature = req.get('X-AiAkaun-Signature') || '';
const timestamp = parseInt(req.get('X-AiAkaun-Timestamp') || '0', 10);
const tolerance = 300;
if (Math.abs(Math.floor(Date.now() / 1000) - timestamp) > tolerance) {
return res.status(400).send('cap masa di luar toleransi');
}
const expected = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${payload}`)
.digest('hex');
const a = Buffer.from(expected, 'utf8');
const b = Buffer.from(signature, 'utf8');
// timingSafeEqual membuang jika panjang berbeza — semak dahulu.
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
return res.status(400).send('tandatangan tidak sah');
}
const event = JSON.parse(payload);
// Nyahduplikasi guna event.id, kemudian balas dengan cepat.
res.status(204).end();
});
app.listen(3000);
Python
import hashlib
import hmac
import os
import time
from flask import Flask, abort, request
app = Flask(__name__)
@app.post("/webhook/aiakaun")
def aiakaun_webhook():
secret = os.environ["AIAKAUN_WEBHOOK_SECRET"].encode()
payload = request.get_data() # bait MENTAH, bukan request.json
signature = request.headers.get("X-AiAkaun-Signature", "")
timestamp = int(request.headers.get("X-AiAkaun-Timestamp", "0"))
tolerance = 300
if abs(int(time.time()) - timestamp) > tolerance:
abort(400, "cap masa di luar toleransi")
signed = f"{timestamp}.".encode() + payload
expected = hmac.new(secret, signed, hashlib.sha256).hexdigest()
# compare_digest, bukan ==. Perbandingan masa-tetap.
if not hmac.compare_digest(expected, signature):
abort(400, "tandatangan tidak sah")
event = request.get_json(force=True)
# Nyahduplikasi guna event["id"], kemudian balas dengan cepat.
return "", 204
Uji penerima anda sebelum bergantung padanya: butang "Hantar ujian" pada setiap endpoint dalam papan pemuka menghantar peristiwa bertandatangan sebenar, dan log penghantaran menunjukkan apa yang pelayan anda balas.
Contoh pantas
Boleh salin-tampal. Tetapkan token anda sekali dahulu:
export AIAKAUN_TOKEN=aia_live_…
Senaraikan transaksi
Perlukan skop read:transactions.
# Senarai transaksi Januari 2026, 100 setiap halaman. curl -G https://aiakaun.com/api/v1/transactions \ -H "Authorization: Bearer $AIAKAUN_TOKEN" \ -H "Accept: application/json" \ -d "from=2026-01-01" \ -d "to=2026-01-31" \ -d "per_page=100"
Cipta transaksi
Perlukan skop write:transactions.
# Cipta satu perbelanjaan. Amaun ialah nombor perpuluhan (RM), bukan sen.
curl -X POST https://aiakaun.com/api/v1/transactions \
-H "Authorization: Bearer $AIAKAUN_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"date": "2026-08-07",
"description": "Sewa pejabat Ogos 2026",
"amount": 1800.00,
"type": "expense",
"account_code": "6200"
}'
Muat naik resit
Perlukan skop write:documents, dan dihadkan kepada 10 muat naik seminit. Respons kembali serta-merta dengan dokumen dalam keadaan menunggu; langgan document.processed untuk mengetahui bila AI selesai membacanya.
# Muat naik resit untuk dibaca AI. multipart/form-data — JANGAN tetapkan # Content-Type sendiri; biar cURL menjananya berserta sempadan (boundary). curl -X POST https://aiakaun.com/api/v1/documents \ -H "Authorization: Bearer $AIAKAUN_TOKEN" \ -H "Accept: application/json" \ -F "file=@resit-ogos.pdf" \ -F "type=receipt"
Tersekat?
Mulakan dengan GET /api/v1/me —
ia mengesahkan token anda, memberitahu syarikat mana yang ia pegang, dan menyenaraikan skopnya. Kebanyakan "API saya tidak berfungsi" ternyata ialah satu skop yang tertinggal. Jika ia masih tidak masuk akal,
hubungi kami.