Teklifler API
Teklifler modülünün tüm işlemleri (13) ve veri modelleri (5): adresler, izinler, girdiler, ön koşullar, olaylar ve örnekler.
PDF’i ve müşterinin kabul ya da reddedebileceği bir bağlantısı olan fiyat teklifleri.
Modül kodu quotes · 13 işlem · 5 veri modeli · 12 olay. Bir anahtar ya da token, arkasındaki kişinin bu modülde yapabildiğinden fazlasını asla yapamaz; satır düzeyindeki güvenlik uygulamadakiyle birebir aynıdır. Yetki kapsamları: quotes (hepsi), quotes:read (yalnız okuma) ya da quotes:<yetenek>.
Kaynaklar
| Kaynak | Tablo | Listeleme ve okuma | POST | PATCH | DELETE |
|---|---|---|---|---|---|
quote_events | quote_event | /api/v1/quote_events | |||
quote_lines | quote_line | /api/v1/quote_lines | |||
quote_templates | quote_template | /api/v1/quote_templates | |||
quote_versions | quote_version | /api/v1/quote_versions | |||
quotes | quote | /api/v1/quotes | quotes.create |
Listeler limit (en çok 200), cursor, order (ör. -created_at), fields ve q alır; diğer her sorgu parametresi bir sütun süzgecidir: ?status=paid, ?total[gte]=100, ?id[in]=a,b, ?x=null.
İşlemler
| İşlem | Gereken izin | Ne yapar |
|---|---|---|
quotes.accept | quotes:write | Kabul edildi işaretle |
quotes.add_note | quotes:write | Not ekle |
quotes.create | quotes:write | Teklif başlat |
quotes.create_template | quotes:manage | Teklif şablonu kaydet |
quotes.delete_template | quotes:manage | Teklif şablonunu sil |
quotes.duplicate | quotes:write | Çoğalt |
quotes.expire_due | quotes:write | Süresi geçen teklifleri düşür |
quotes.reject | quotes:write | Reddedildi işaretle |
quotes.revise | quotes:write | Yeni sürüme revize et |
quotes.send | quotes:write | E-postayla gönder |
quotes.update_draft | quotes:write | Taslak teklifi düzenle |
quotes.update_template | quotes:manage | Teklif şablonunu düzenle |
quotes.withdraw | quotes:write | Geri çek |
quotes.accept
Kabul edildi işaretle — Müşterinin mevcut sürüme evetini kaydeder; finans ondan sözleşme taslağı hazırlar.
Gereken izin quotes:write · dışarıya ulaşır (gönderir, yayımlar ya da ücret alır) · Era çalıştırırken bir kişiye onaylatır
https://app.getera.io/api/v1/quotes/{id}/actions/accept- Asıl adres:
POST /api/v1/actions/quotes.accept
Girdi
| Alan | Tür | Zorunlu | Açıklama |
|---|---|---|---|
id | uuid | evet | Doldurulduğu yer: adresteki {id} · Teklif · kimliği: quote |
name | string | Yanıtlayan · en çok 200 | |
note | string | Not · en çok 4000 | |
via | string (enum) | Nasıl · İzin verilen değerler: manual, link | |
signatureName | string | Yazılı imza · en çok 200 | |
ip | string | Gönderen adresi · en çok 64 | |
userAgent | string | Tarayıcı · en çok 400 |
Ön koşullar
Koşul tutmazsa işlem 409 ve şu kodlardan biriyle reddedilir:
| Kod | Ne zaman reddedilir |
|---|---|
quote_not_found | Teklif bulunmalı. |
quote_not_open | Yalnızca gönderilmiş bir teklif yanıtlanır. |
quote_validity_passed | Geçerlilik günü geçmiş bir teklif kabul edilmez. |
quote_signature_required | Bağlantıdan kabul etmek müşterinin adını yazmasını gerektirir. |
Yayımladığı olaylar: quotes.accepted
Neye yazar: quote (update) — Marks it accepted, freezes the accepted version and keeps the typed signature; quote_event (insert) — Records the answer
curl -X POST https://app.getera.io/api/v1/quotes/QUOTE_ID/actions/accept \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"name":"Answered by"}'{
"ok": true,
"result": "…",
"events": [
"quotes.accepted"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.quotes.accept("QUOTE_ID", {
name: "Answered by"
})era quotes accept QUOTE_ID \
--name "Answered by"{
"name": "era__quotes__accept",
"arguments": {
"id": "QUOTE_ID",
"name": "Answered by"
}
}Hatalar: 401 kimlik bilgisi yok ya da süresi dolmuş · 403 kimlik bilgisinde quotes:write izni yok · 404 kayıt ya da modül erişim dışında · 422 geçersiz girdi (problems[]) · 409 quote_not_found, quote_not_open, quote_validity_passed, quote_signature_required · 429 çok sık istek
quotes.add_note
Not ekle — Teklifin kendi geçmişine bir satır.
Gereken izin quotes:write · veriyi değiştirir
https://app.getera.io/api/v1/quote_events/actions/add_note- Asıl adres:
POST /api/v1/actions/quotes.add_note
Girdi
| Alan | Tür | Zorunlu | Açıklama |
|---|---|---|---|
id | uuid | evet | Teklif · kimliği: quote |
message | string | evet | Not · en çok 4000 |
Ön koşullar
Koşul tutmazsa işlem 409 ve şu kodlardan biriyle reddedilir:
| Kod | Ne zaman reddedilir |
|---|---|
quote_not_found | Teklif bulunmalı. |
Yayımladığı olaylar: quotes.note_added
Neye yazar: quote_event (insert) — Records the note
curl -X POST https://app.getera.io/api/v1/quote_events/actions/add_note \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"id":"QUOTE_ID","message":"Note"}'{
"ok": true,
"result": "…",
"events": [
"quotes.note_added"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.quoteEvents.addNote({
id: "QUOTE_ID",
message: "Note"
})era quote_events add_note \
--id "QUOTE_ID" \
--message "Note"{
"name": "era__quotes__add_note",
"arguments": {
"id": "QUOTE_ID",
"message": "Note"
}
}Hatalar: 401 kimlik bilgisi yok ya da süresi dolmuş · 403 kimlik bilgisinde quotes:write izni yok · 404 kayıt ya da modül erişim dışında · 422 geçersiz girdi (problems[]) · 409 quote_not_found · 429 çok sık istek
quotes.create
Teklif başlat — İlk sürümü ve satırlarıyla numaralı bir taslak teklif; her satırda dondurulmuş vergi bilgisi.
Gereken izin quotes:write · veriyi değiştirir
https://app.getera.io/api/v1/quotes/actions/create- REST kısayolu:
POST /api/v1/quotes - Asıl adres:
POST /api/v1/actions/quotes.create
Girdi
| Alan | Tür | Zorunlu | Açıklama |
|---|---|---|---|
customerId | uuid | İçin · kimliği: customer | |
leadId | uuid | Potansiyel müşteri | |
templateId | uuid | Şablondan · kimliği: quote_template | |
title | string | Başlık · en çok 200 | |
currency | string | Para birimi · en çok 3 | |
taxCountry | string | Vergi ülkesi · en çok 2 | |
validUntil | date | Geçerlilik | |
notes | string | Notlar · en çok 4000 | |
lines | object / array | Kalemler |
Ön koşullar
Koşul tutmazsa işlem 409 ve şu kodlardan biriyle reddedilir:
| Kod | Ne zaman reddedilir |
|---|---|
customer_not_found | Kişi bulunmalı. |
quote_template_not_found | Belirtilen şablon bulunmalı. |
customer_archived | Arşivlenmiş bir kişiye teklif verilmez. |
invalid_currency | Para birimi bir ISO-4217 kodu olmalı. |
quote_needs_lines | Teklifin en az bir satırı olmalı. |
invalid_quote_lines | Her satırın bir açıklaması, pozitif miktarı ve fiyatı olmalı; katalog ürünü bulunmalı. |
Yayımladığı olaylar: quotes.created
Neye yazar: quote (insert) — Opens the quote with its number; quote_version (insert) — Writes version 1; quote_line (insert) — Writes its lines with their tax snapshot; quote_event (insert) — Records that it was created
curl -X POST https://app.getera.io/api/v1/quotes/actions/create \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"customerId":"CUSTOMER_ID"}'{
"ok": true,
"result": "…",
"events": [
"quotes.created"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.quotes.create({
customerId: "CUSTOMER_ID"
})era quotes create \
--customer-id "CUSTOMER_ID"{
"name": "era__quotes__create",
"arguments": {
"customerId": "CUSTOMER_ID"
}
}Hatalar: 401 kimlik bilgisi yok ya da süresi dolmuş · 403 kimlik bilgisinde quotes:write izni yok · 404 kayıt ya da modül erişim dışında · 422 geçersiz girdi (problems[]) · 409 customer_not_found, quote_template_not_found, customer_archived, invalid_currency, quote_needs_lines, invalid_quote_lines · 429 çok sık istek
quotes.create_template
Teklif şablonu kaydet — Yeniden kullanılabilir başlık, notlar ve satırlar — yazılarak ya da bir tekliften kaydedilerek.
Gereken izin quotes:manage · veriyi değiştirir
https://app.getera.io/api/v1/quote_templates/actions/create_template- Asıl adres:
POST /api/v1/actions/quotes.create_template
Girdi
| Alan | Tür | Zorunlu | Açıklama |
|---|---|---|---|
name | string | evet | Şablon adı · en çok 120 |
title | string | Teklif başlığı · en çok 200 | |
notes | string | Müşteri için notlar · en çok 4000 | |
currency | string | Para birimi · en çok 3 | |
lines | object / array | Kalemler | |
fromQuoteId | uuid | Tekliften · kimliği: quote |
Ön koşullar
Koşul tutmazsa işlem 409 ve şu kodlardan biriyle reddedilir:
| Kod | Ne zaman reddedilir |
|---|---|
quote_template_name_taken | Şablon adları çalışma alanında benzersizdir. |
quote_not_found | Teklif bulunmalı. |
invalid_currency | Para birimi bir ISO-4217 kodu olmalı. |
quote_needs_lines | Teklifin en az bir satırı olmalı. |
invalid_quote_lines | Her satırın bir açıklaması, pozitif miktarı ve fiyatı olmalı; katalog ürünü bulunmalı. |
Yayımladığı olaylar: quotes.template_changed
Neye yazar: quote_template (insert) — Saves the template; quote_event (insert) — Notes on the quote that it was saved as a template
curl -X POST https://app.getera.io/api/v1/quote_templates/actions/create_template \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"name":"Template name"}'{
"ok": true,
"result": "…",
"events": [
"quotes.template_changed"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.quoteTemplates.createTemplate({
name: "Template name"
})era quote_templates create_template \
--name "Template name"{
"name": "era__quotes__create_template",
"arguments": {
"name": "Template name"
}
}Hatalar: 401 kimlik bilgisi yok ya da süresi dolmuş · 403 kimlik bilgisinde quotes:manage izni yok · 404 kayıt ya da modül erişim dışında · 422 geçersiz girdi (problems[]) · 409 quote_template_name_taken, quote_not_found, invalid_currency, quote_needs_lines, invalid_quote_lines · 429 çok sık istek
quotes.delete_template
Teklif şablonunu sil — Şablonu kaldırır; ondan yapılmış tekliflere dokunulmaz.
Gereken izin quotes:manage · siler ya da geri alınamaz · Era çalıştırırken bir kişiye onaylatır
https://app.getera.io/api/v1/quote_templates/{id}/actions/delete_template- Asıl adres:
POST /api/v1/actions/quotes.delete_template
Girdi
| Alan | Tür | Zorunlu | Açıklama |
|---|---|---|---|
id | uuid | evet | Doldurulduğu yer: adresteki {id} · Şablon · kimliği: quote_template |
Ön koşullar
Koşul tutmazsa işlem 409 ve şu kodlardan biriyle reddedilir:
| Kod | Ne zaman reddedilir |
|---|---|
quote_template_not_found | Şablon bulunmalı. |
Yayımladığı olaylar: quotes.template_changed
Neye yazar: quote_template (delete) — Deletes the template
curl -X POST https://app.getera.io/api/v1/quote_templates/QUOTE_TEMPLATE_ID/actions/delete_template \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{}'{
"ok": true,
"result": "…",
"events": [
"quotes.template_changed"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.quoteTemplates.deleteTemplate("QUOTE_TEMPLATE_ID")era quote_templates delete_template QUOTE_TEMPLATE_ID{
"name": "era__quotes__delete_template",
"arguments": {
"id": "QUOTE_TEMPLATE_ID"
}
}Hatalar: 401 kimlik bilgisi yok ya da süresi dolmuş · 403 kimlik bilgisinde quotes:manage izni yok · 404 kayıt ya da modül erişim dışında · 422 geçersiz girdi (problems[]) · 409 quote_template_not_found · 429 çok sık istek
quotes.duplicate
Çoğalt — Aynı satırlarla yeni bir taslak teklif — aynı kişi ya da başkası için.
Gereken izin quotes:write · veriyi değiştirir
https://app.getera.io/api/v1/quotes/{id}/actions/duplicate- Asıl adres:
POST /api/v1/actions/quotes.duplicate
Girdi
| Alan | Tür | Zorunlu | Açıklama |
|---|---|---|---|
id | uuid | evet | Doldurulduğu yer: adresteki {id} · Teklif · kimliği: quote |
customerId | uuid | İçin · kimliği: customer |
Ön koşullar
Koşul tutmazsa işlem 409 ve şu kodlardan biriyle reddedilir:
| Kod | Ne zaman reddedilir |
|---|---|
quote_not_found | Teklif bulunmalı. |
customer_not_found | Kişi bulunmalı. |
customer_archived | Arşivlenmiş bir kişiye teklif verilmez. |
quote_needs_lines | Teklifin en az bir satırı olmalı. |
invalid_quote_lines | Her satırın bir açıklaması, pozitif miktarı ve fiyatı olmalı; katalog ürünü bulunmalı. |
Yayımladığı olaylar: quotes.created, quotes.duplicated
Neye yazar: quote (insert) — Opens the copy with its own number; quote_version (insert) — Writes version 1; quote_line (insert) — Copies the lines, re-priced; quote_event (insert) — Records where it came from; quote (update) — Remembers the original
curl -X POST https://app.getera.io/api/v1/quotes/QUOTE_ID/actions/duplicate \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"customerId":"CUSTOMER_ID"}'{
"ok": true,
"result": "…",
"events": [
"quotes.created",
"quotes.duplicated"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.quotes.duplicate("QUOTE_ID", {
customerId: "CUSTOMER_ID"
})era quotes duplicate QUOTE_ID \
--customer-id "CUSTOMER_ID"{
"name": "era__quotes__duplicate",
"arguments": {
"id": "QUOTE_ID",
"customerId": "CUSTOMER_ID"
}
}Hatalar: 401 kimlik bilgisi yok ya da süresi dolmuş · 403 kimlik bilgisinde quotes:write izni yok · 404 kayıt ya da modül erişim dışında · 422 geçersiz girdi (problems[]) · 409 quote_not_found, customer_not_found, customer_archived, quote_needs_lines, invalid_quote_lines · 429 çok sık istek
quotes.expire_due
Süresi geçen teklifleri düşür — Otomatik günlük iş: geçerlilik günü geçmiş gönderilmiş teklif süresi doldu olur.
Gereken izin quotes:write · veriyi değiştirir
403 machine_only).https://app.getera.io/api/v1/quote_events/actions/expire_due- Asıl adres:
POST /api/v1/actions/quotes.expire_due
Girdi
Bu işlem girdi almaz.
Yayımladığı olaylar: quotes.expired
Neye yazar: quote (update) — Marks overdue quotes expired; quote_event (insert) — Records the lapse on each
Hatalar: 401 kimlik bilgisi yok ya da süresi dolmuş · 403 kimlik bilgisinde quotes:write izni yok · 404 kayıt ya da modül erişim dışında · 422 geçersiz girdi (problems[]) · 429 çok sık istek
quotes.reject
Reddedildi işaretle — Müşterinin hayırını, verdiyse nedeniyle kaydeder.
Gereken izin quotes:write · veriyi değiştirir
https://app.getera.io/api/v1/quotes/{id}/actions/reject- Asıl adres:
POST /api/v1/actions/quotes.reject
Girdi
| Alan | Tür | Zorunlu | Açıklama |
|---|---|---|---|
id | uuid | evet | Doldurulduğu yer: adresteki {id} · Teklif · kimliği: quote |
name | string | Yanıtlayan · en çok 200 | |
note | string | Not · en çok 4000 | |
via | string (enum) | Nasıl · İzin verilen değerler: manual, link | |
signatureName | string | Yazılı imza · en çok 200 | |
ip | string | Gönderen adresi · en çok 64 | |
userAgent | string | Tarayıcı · en çok 400 |
Ön koşullar
Koşul tutmazsa işlem 409 ve şu kodlardan biriyle reddedilir:
| Kod | Ne zaman reddedilir |
|---|---|
quote_not_found | Teklif bulunmalı. |
quote_not_open | Yalnızca gönderilmiş bir teklif yanıtlanır. |
Yayımladığı olaylar: quotes.rejected
Neye yazar: quote (update) — Marks it declined; quote_event (insert) — Records the answer
curl -X POST https://app.getera.io/api/v1/quotes/QUOTE_ID/actions/reject \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"name":"Answered by"}'{
"ok": true,
"result": "…",
"events": [
"quotes.rejected"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.quotes.reject("QUOTE_ID", {
name: "Answered by"
})era quotes reject QUOTE_ID \
--name "Answered by"{
"name": "era__quotes__reject",
"arguments": {
"id": "QUOTE_ID",
"name": "Answered by"
}
}Hatalar: 401 kimlik bilgisi yok ya da süresi dolmuş · 403 kimlik bilgisinde quotes:write izni yok · 404 kayıt ya da modül erişim dışında · 422 geçersiz girdi (problems[]) · 409 quote_not_found, quote_not_open · 429 çok sık istek
quotes.revise
Yeni sürüme revize et — Gönderilen sürümü yeni bir taslak sürüme kopyalar; eski bağlantı yanıt vermez olur.
Gereken izin quotes:write · veriyi değiştirir
https://app.getera.io/api/v1/quotes/{id}/actions/revise- Asıl adres:
POST /api/v1/actions/quotes.revise
Girdi
| Alan | Tür | Zorunlu | Açıklama |
|---|---|---|---|
id | uuid | evet | Doldurulduğu yer: adresteki {id} · Teklif · kimliği: quote |
Ön koşullar
Koşul tutmazsa işlem 409 ve şu kodlardan biriyle reddedilir:
| Kod | Ne zaman reddedilir |
|---|---|
quote_not_found | Teklif bulunmalı. |
quote_not_revisable | Yalnızca gönderilmiş, reddedilmiş veya süresi geçmiş bir teklif revize edilir. |
Yayımladığı olaylar: quotes.revised
Neye yazar: quote_version (insert) — Writes the new version; quote_line (insert) — Copies the lines; quote (update) — Points at the new version, back to draft; quote_event (insert) — Records the revision
curl -X POST https://app.getera.io/api/v1/quotes/QUOTE_ID/actions/revise \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{}'{
"ok": true,
"result": "…",
"events": [
"quotes.revised"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.quotes.revise("QUOTE_ID")era quotes revise QUOTE_ID{
"name": "era__quotes__revise",
"arguments": {
"id": "QUOTE_ID"
}
}Hatalar: 401 kimlik bilgisi yok ya da süresi dolmuş · 403 kimlik bilgisinde quotes:write izni yok · 404 kayıt ya da modül erişim dışında · 422 geçersiz girdi (problems[]) · 409 quote_not_found, quote_not_revisable · 429 çok sık istek
quotes.send
E-postayla gönder — Mevcut sürümü kabul veya ret bağlantısıyla e-postayla gönderir; kayıt, gidip gitmediğini gösterir.
Gereken izin quotes:write · dışarıya ulaşır (gönderir, yayımlar ya da ücret alır) · Era çalıştırırken bir kişiye onaylatır
https://app.getera.io/api/v1/quotes/{id}/actions/send- Asıl adres:
POST /api/v1/actions/quotes.send
Girdi
| Alan | Tür | Zorunlu | Açıklama |
|---|---|---|---|
id | uuid | evet | Doldurulduğu yer: adresteki {id} · Teklif · kimliği: quote |
to | string | E-posta · en çok 320 | |
message | string | Mesaj · en çok 4000 |
Ön koşullar
Koşul tutmazsa işlem 409 ve şu kodlardan biriyle reddedilir:
| Kod | Ne zaman reddedilir |
|---|---|
quote_not_found | Teklif bulunmalı. |
quote_not_sendable | Yalnızca taslak veya açık bir teklif gönderilir. |
quote_validity_passed | Geçerlilik günü geçmiş bir teklif gönderilmez. |
quote_needs_lines | Teklifin en az bir satırı olmalı. |
quote_recipient_missing | Gönderilecek bir adres olmalı. |
Yayımladığı olaylar: quotes.send_requested, quotes.sent
Neye yazar: quote (update) — Marks it sent and mints its answer link; quote_version (update) — Stamps when this version was sent; quote_event (insert) — Records who it was sent to
curl -X POST https://app.getera.io/api/v1/quotes/QUOTE_ID/actions/send \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"to":"Email"}'{
"ok": true,
"result": "…",
"events": [
"quotes.send_requested",
"quotes.sent"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.quotes.send("QUOTE_ID", {
to: "Email"
})era quotes send QUOTE_ID \
--to "Email"{
"name": "era__quotes__send",
"arguments": {
"id": "QUOTE_ID",
"to": "Email"
}
}Hatalar: 401 kimlik bilgisi yok ya da süresi dolmuş · 403 kimlik bilgisinde quotes:write izni yok · 404 kayıt ya da modül erişim dışında · 422 geçersiz girdi (problems[]) · 409 quote_not_found, quote_not_sendable, quote_validity_passed, quote_needs_lines, quote_recipient_missing · 429 çok sık istek
quotes.update_draft
Taslak teklifi düzenle — Başlığı, satırları, geçerliliği veya notları değiştirir — yalnızca mevcut sürüm taslakken.
Gereken izin quotes:write · veriyi değiştirir
https://app.getera.io/api/v1/quotes/{id}/actions/update_draft- Asıl adres:
POST /api/v1/actions/quotes.update_draft
Girdi
| Alan | Tür | Zorunlu | Açıklama |
|---|---|---|---|
id | uuid | evet | Doldurulduğu yer: adresteki {id} · Teklif · kimliği: quote |
title | string | Başlık · en çok 200 | |
validUntil | date | Geçerlilik | |
notes | string | Notlar · en çok 4000 | |
taxCountry | string | Vergi ülkesi · en çok 2 | |
lines | object / array | Kalemler |
Ön koşullar
Koşul tutmazsa işlem 409 ve şu kodlardan biriyle reddedilir:
| Kod | Ne zaman reddedilir |
|---|---|
quote_not_found | Teklif bulunmalı. |
quote_not_draft | Yalnızca taslak düzenlenir. |
quote_needs_lines | Teklifin en az bir satırı olmalı. |
invalid_quote_lines | Her satırın bir açıklaması, pozitif miktarı ve fiyatı olmalı; katalog ürünü bulunmalı. |
Yayımladığı olaylar: quotes.updated
Neye yazar: quote (update) — Updates the title; quote_version (update) — Updates validity, notes and totals; quote_line (upsert) — Rewrites the lines; quote_event (insert) — Records the edit
curl -X POST https://app.getera.io/api/v1/quotes/QUOTE_ID/actions/update_draft \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"title":"Title"}'{
"ok": true,
"result": "…",
"events": [
"quotes.updated"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.quotes.updateDraft("QUOTE_ID", {
title: "Title"
})era quotes update_draft QUOTE_ID \
--title "Title"{
"name": "era__quotes__update_draft",
"arguments": {
"id": "QUOTE_ID",
"title": "Title"
}
}Hatalar: 401 kimlik bilgisi yok ya da süresi dolmuş · 403 kimlik bilgisinde quotes:write izni yok · 404 kayıt ya da modül erişim dışında · 422 geçersiz girdi (problems[]) · 409 quote_not_found, quote_not_draft, quote_needs_lines, invalid_quote_lines · 429 çok sık istek
quotes.update_template
Teklif şablonunu düzenle — Şablonu değiştirir; ondan yapılmış teklifler kendi kopyalarını korur.
Gereken izin quotes:manage · veriyi değiştirir
https://app.getera.io/api/v1/quote_templates/{id}/actions/update_template- Asıl adres:
POST /api/v1/actions/quotes.update_template
Girdi
| Alan | Tür | Zorunlu | Açıklama |
|---|---|---|---|
id | uuid | evet | Doldurulduğu yer: adresteki {id} · Şablon · kimliği: quote_template |
name | string | Şablon adı · en çok 120 | |
title | string | Teklif başlığı · en çok 200 | |
notes | string | Müşteri için notlar · en çok 4000 | |
currency | string | Para birimi · en çok 3 | |
lines | object / array | Kalemler |
Ön koşullar
Koşul tutmazsa işlem 409 ve şu kodlardan biriyle reddedilir:
| Kod | Ne zaman reddedilir |
|---|---|
quote_template_not_found | Şablon bulunmalı. |
quote_template_name_taken | Şablon adları çalışma alanında benzersizdir. |
quote_needs_lines | Teklifin en az bir satırı olmalı. |
invalid_quote_lines | Her satırın bir açıklaması, pozitif miktarı ve fiyatı olmalı; katalog ürünü bulunmalı. |
Yayımladığı olaylar: quotes.template_changed
Neye yazar: quote_template (update) — Rewrites the template
curl -X POST https://app.getera.io/api/v1/quote_templates/QUOTE_TEMPLATE_ID/actions/update_template \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"name":"Template name"}'{
"ok": true,
"result": "…",
"events": [
"quotes.template_changed"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.quoteTemplates.updateTemplate("QUOTE_TEMPLATE_ID", {
name: "Template name"
})era quote_templates update_template QUOTE_TEMPLATE_ID \
--name "Template name"{
"name": "era__quotes__update_template",
"arguments": {
"id": "QUOTE_TEMPLATE_ID",
"name": "Template name"
}
}Hatalar: 401 kimlik bilgisi yok ya da süresi dolmuş · 403 kimlik bilgisinde quotes:manage izni yok · 404 kayıt ya da modül erişim dışında · 422 geçersiz girdi (problems[]) · 409 quote_template_not_found, quote_template_name_taken, quote_needs_lines, invalid_quote_lines · 429 çok sık istek
quotes.withdraw
Geri çek — Taslak veya açık bir teklifi masadan kaldırır; bağlantısı yanıt vermez olur.
Gereken izin quotes:write · dışarıya ulaşır (gönderir, yayımlar ya da ücret alır) · Era çalıştırırken bir kişiye onaylatır
https://app.getera.io/api/v1/quotes/{id}/actions/withdraw- Asıl adres:
POST /api/v1/actions/quotes.withdraw
Girdi
| Alan | Tür | Zorunlu | Açıklama |
|---|---|---|---|
id | uuid | evet | Doldurulduğu yer: adresteki {id} · Teklif · kimliği: quote |
reason | string | Neden · en çok 2000 |
Ön koşullar
Koşul tutmazsa işlem 409 ve şu kodlardan biriyle reddedilir:
| Kod | Ne zaman reddedilir |
|---|---|
quote_not_found | Teklif bulunmalı. |
quote_not_withdrawable | Yalnızca taslak veya açık bir teklif geri çekilir. |
Yayımladığı olaylar: quotes.withdrawn
Neye yazar: quote (update) — Marks it withdrawn; quote_event (insert) — Records why
curl -X POST https://app.getera.io/api/v1/quotes/QUOTE_ID/actions/withdraw \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"reason":"Reason"}'{
"ok": true,
"result": "…",
"events": [
"quotes.withdrawn"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.quotes.withdraw("QUOTE_ID", {
reason: "Reason"
})era quotes withdraw QUOTE_ID \
--reason "Reason"{
"name": "era__quotes__withdraw",
"arguments": {
"id": "QUOTE_ID",
"reason": "Reason"
}
}Hatalar: 401 kimlik bilgisi yok ya da süresi dolmuş · 403 kimlik bilgisinde quotes:write izni yok · 404 kayıt ya da modül erişim dışında · 422 geçersiz girdi (problems[]) · 409 quote_not_found, quote_not_withdrawable · 429 çok sık istek
Veri modelleri
QuoteEvent
Tablo quote_event · Kaynak quote_events
GET /api/v1/quote_eventsGET /api/v1/quote_events/{id}
| Sütun | Tür | Boş olabilir | İzin verilen değerler | Bağlı olduğu tablo |
|---|---|---|---|---|
id | string (uuid) · uuid | |||
organization_id | string (uuid) · uuid | organization | ||
workspace_id | string (uuid) · uuid | workspace | ||
quote_id | string (uuid) · uuid | quote | ||
type | string · text | created, updated, revised, send_requested, accepted, rejected, expired, withdrawn, note_added, duplicated, template_saved | ||
message | string · text | evet | ||
parameters | object · jsonb | |||
actor_user_id | string (uuid) · uuid | evet | app_user | |
occurred_at | string (date-time) · timestamptz |
Birincil anahtar: id
QuoteLine
Tablo quote_line · Kaynak quote_lines
GET /api/v1/quote_linesGET /api/v1/quote_lines/{id}
| Sütun | Tür | Boş olabilir | İzin verilen değerler | Bağlı olduğu tablo |
|---|---|---|---|---|
id | string (uuid) · uuid | |||
organization_id | string (uuid) · uuid | organization | ||
workspace_id | string (uuid) · uuid | workspace | ||
quote_id | string (uuid) · uuid | quote | ||
version_id | string (uuid) · uuid | quote_version | ||
description | string · text | |||
quantity | string (decimal) · numeric | |||
item_variant_id | string (uuid) · uuid | evet | item_variant | |
currency | string · bpchar | en çok 3 | ||
unit_amount | string (int64) · int8 | |||
discount_amount | string (int64) · int8 | |||
tax_class_id | string (uuid) · uuid | evet | tax_class | |
tax_class_name | string · text | evet | ||
tax_rate | string (decimal) · numeric | |||
prices_entered_with_tax | boolean · bool | |||
net_amount | string (int64) · int8 | |||
tax_amount | string (int64) · int8 | |||
total_amount | string (int64) · int8 | |||
display_order | integer · int4 | |||
created_at | string (date-time) · timestamptz |
Birincil anahtar: id
Denetimler:
CHECK ((currency ~ '^[A-Z]{3}$'::text))CHECK ((discount_amount >= 0))CHECK ((net_amount >= 0))CHECK ((quantity > (0)::numeric))CHECK ((tax_amount >= 0))CHECK (((tax_rate >= (0)::numeric) AND (tax_rate <= (100)::numeric)))CHECK ((total_amount >= 0))CHECK ((unit_amount >= 0))
QuoteTemplate
Tablo quote_template · Kaynak quote_templates
GET /api/v1/quote_templatesGET /api/v1/quote_templates/{id}
| Sütun | Tür | Boş olabilir | İzin verilen değerler | Bağlı olduğu tablo |
|---|---|---|---|---|
id | string (uuid) · uuid | |||
organization_id | string (uuid) · uuid | organization | ||
workspace_id | string (uuid) · uuid | workspace | ||
name | string · text | |||
title | string · text | |||
notes | string · text | evet | ||
currency | string · bpchar | evet | en çok 3 | |
lines | object · jsonb | |||
created_by_user_id | string (uuid) · uuid | evet | app_user | |
created_at | string (date-time) · timestamptz | |||
updated_at | string (date-time) · timestamptz |
Birincil anahtar: id
Denetimler:
CHECK (((currency IS NULL) OR (currency ~ '^[A-Z]{3}$'::text)))CHECK ((jsonb_typeof(lines) = 'array'::text))CHECK ((length(TRIM(BOTH FROM name)) > 0))CHECK ((length(TRIM(BOTH FROM title)) > 0))
QuoteVersion
Tablo quote_version · Kaynak quote_versions
GET /api/v1/quote_versionsGET /api/v1/quote_versions/{id}
| Sütun | Tür | Boş olabilir | İzin verilen değerler | Bağlı olduğu tablo |
|---|---|---|---|---|
id | string (uuid) · uuid | |||
organization_id | string (uuid) · uuid | organization | ||
workspace_id | string (uuid) · uuid | workspace | ||
quote_id | string (uuid) · uuid | quote | ||
version_no | integer · int4 | |||
currency | string · bpchar | en çok 3 | ||
tax_country | string · bpchar | evet | en çok 2 | |
valid_until | string (date) · date | evet | ||
notes | string · text | evet | ||
subtotal_amount | string (int64) · int8 | |||
discount_total_amount | string (int64) · int8 | |||
tax_total_amount | string (int64) · int8 | |||
total_amount | string (int64) · int8 | |||
sent_at | string (date-time) · timestamptz | evet | ||
created_by_user_id | string (uuid) · uuid | evet | app_user | |
created_at | string (date-time) · timestamptz | |||
updated_at | string (date-time) · timestamptz |
Birincil anahtar: id
Tekil: quote_id, version_no
Denetimler:
CHECK ((currency ~ '^[A-Z]{3}$'::text))CHECK ((discount_total_amount >= 0))CHECK ((subtotal_amount >= 0))CHECK (((tax_country IS NULL) OR (tax_country ~ '^[A-Z]{2}$'::text)))CHECK ((tax_total_amount >= 0))CHECK ((total_amount >= 0))CHECK ((version_no >= 1))
Quote
Tablo quote · Kaynak quotes
GET /api/v1/quotesGET /api/v1/quotes/{id}POST /api/v1/quotes→quotes.create
| Sütun | Tür | Boş olabilir | İzin verilen değerler | Bağlı olduğu tablo |
|---|---|---|---|---|
id | string (uuid) · uuid | |||
organization_id | string (uuid) · uuid | organization | ||
workspace_id | string (uuid) · uuid | workspace | ||
number | string · text | |||
title | string · text | |||
status | string · text | draft, sent, accepted, rejected, expired, withdrawn | ||
customer_id | string (uuid) · uuid | customer | ||
lead_id | string (uuid) · uuid | evet | ||
owner_user_id | string (uuid) · uuid | evet | app_user | |
current_version_id | string (uuid) · uuid | evet | quote_version | |
accepted_version_id | string (uuid) · uuid | evet | quote_version | |
link_expires_at | string (date-time) · timestamptz | evet | ||
last_viewed_at | string (date-time) · timestamptz | evet | ||
sent_at | string (date-time) · timestamptz | evet | ||
responded_at | string (date-time) · timestamptz | evet | ||
response_name | string · text | evet | ||
response_note | string · text | evet | ||
responded_via | string · text | evet | ||
withdrawn_at | string (date-time) · timestamptz | evet | ||
created_by_user_id | string (uuid) · uuid | evet | app_user | |
created_at | string (date-time) · timestamptz | |||
updated_at | string (date-time) · timestamptz | |||
signature_name | string · text | evet | ||
signed_at | string (date-time) · timestamptz | evet | ||
signature_ip | string · text | evet | ||
signature_user_agent | string · text | evet | ||
duplicated_from_id | string (uuid) · uuid | evet | quote | |
template_id | string (uuid) · uuid | evet | quote_template |
Birincil anahtar: id
Denetimler:
CHECK (((responded_via IS NULL) OR (responded_via = ANY (ARRAY['link'::text, 'manual'::text]))))CHECK ((length(TRIM(BOTH FROM title)) > 0))
Olaylar
İş akışları ve webhook'lar bu olaylara tepki verir.
| Olay | Ne olur | Taşıdığı alanlar |
|---|---|---|
quotes.accepted | Müşteri bir teklifi kabul etti. | id, number, customerId, leadId, ownerUserId, versionNo, totalAmount, currency, description, lines, via |
quotes.created | Bir teklif başlatıldı. | id, number, customerId, leadId, ownerUserId, totalAmount, currency |
quotes.duplicated | Bir teklif yeni bir taslağa kopyalandı. | id, fromId, ownerUserId |
quotes.expired | Gönderilen bir teklifin süresi yanıt alınmadan doldu. | id, number, ownerUserId |
quotes.note_added | Bir teklife not eklendi. | id |
quotes.rejected | Müşteri bir teklifi reddetti. | id, number, customerId, ownerUserId, reason, via |
quotes.revised | Bir teklif yeni bir sürüm olarak revize edildi. | id, versionNo |
quotes.send_requested | Bir teklif e-postayla gönderildi; bildirimler teslim eder. | id, eventId, to |
quotes.sent | Bir teklif müşteriye gitti. | id, number, customerId, ownerUserId, versionNo |
quotes.template_changed | Bir teklif şablonu kaydedildi, düzenlendi ya da silindi. | id |
quotes.updated | Taslak bir teklif düzenlendi. | id |
quotes.withdrawn | Bir teklif geri çekildi. | id, ownerUserId |