# Customer Support／Ticketing API × Agent

CURRENT_STATUS: CURRENT
OBSERVATION: SPEC_ONLY
FRESHNESS: CURRENT
PAGE_TYPE: reference
CANONICAL_URL: /tools/ea-226-customer-support-ticketing-api-agent
CLAIM_IDS: none
EVIDENCE_IDS: EVD-EA-226-URL-EC2CB7D759A7, EVD-EA-226-URL-6447877A5EBE, EVD-EA-226-URL-995D6C4E25E3, EVD-EA-226-URL-3E80FE253464, EVD-EA-226-URL-C2E80886F662, EVD-EA-226-URL-CD6CC7899CCA, EA-226-CURRENT-APPROVAL, EA-226-CURRENT-BODY-READBACK
UNKNOWN_IDS: EA-226-UNKNOWN-01
OPS_IDS: none

## Summary
Customer Support／Ticketing API連携では、分類・回答草案・人への引継ぎ・顧客への送信・状態更新を別の操作として管理する。内部メモは公開範囲を明示し、承認した本文と対象を送信前に照合する。更新競合の制御は各リクエストの実際のペイロードで確認し、応答後もチケット状態を再読込する。古い利用者報告には、SDKの別リクエストによる部分変更や、HTTP200後に意図した変更が確認できなかった例がある。今回のZenpy2.0.55検査は送出ペイロードの検査であり、実顧客への通知・現行サーバーの競合制御・SDK全版の挙動を保証しない。

## Current judgment
C1 PRIVATE_DRAFT_BOUNDARY. Real SDK update with Comment(body='draft',public=False) produced ticket.comment.public=false. Omitting public produced no outgoing visibility field. Combined with S2 this means a draft must explicitly state intended visibility rather than relying on omission. Runtime verifies bytes, not server audience, routing or notification. Human approval should bind draft hash, requester/channel and public/private choice; classification and escalation do not imply permission to send a customer reply. This approval design is a proposal, not a built-in Zendesk guarantee.
C2 CONCURRENCY_GUARDS_MUST_REACH_EACH_REQUEST. Real Zenpy update included safe_update:true and updated_stamp:'2026-10-05T00:00:00Z' in the single ticket payload. That timestamp is artificial; production requires authoritative last read. S1 documents conflict handling; S3 is historical counterevidence to assuming a high-level SDK save is one guarded atomic action. Trace every affected endpoint and independently reconcile after partial failure. Our Zenpy fixture does not reproduce Ruby #420, prove its current fix, or test real409 enforcement.
C3 SUCCESS_RESPONSE_NOT_INTENDED_STATE. S4 is a bounded historical firsthand counterexample. The injected successful Zenpy response cannot prove a remote ticket really changed. Read back exact fields, public/private comment and actor/approver provenance; separate acknowledged request from completed outcome. If update timed out or a multipart save partly failed, mark outcomeunknown and reconcile before repeating comments or external messages.
C4 EMPTY_ARRAY_IS_AN_EXPLICIT_CHANGE. Real SDK Ticket(id123,tags=[]) emitted tags:[], rather than omitting tags. The server effect is untested. Do not replace the ticket's full tag set merely to classify it without an approved change set and concurrency review. Proposed rule: preserve unrelated human assignments/tags and re-evaluate intent after a stale-state conflict; no unconditional retry that overwrites the new state.
C5 ASYNC_AND_AUDIT_BOUNDARIES. S1 documents a distinction between accepted async job and available completed ticket, and between changed update and audit creation. A job must be reconciled to resulting ticket; absence of a newly created remote audit cannot be the only integration execution log. This is documented behavior, not runtime reproduction here.

## Scope
Current directly read proposal Doc 1_9XrDkXlopnx39HlRa1YDO8yRvOEBXup2vvY6senU7s t.0:27850–28133 distinguishes Zendesk classification, draft, knowledge retrieval, escalation and ticket update; automated customer reply and human handoff must be separate. Retreat 1Vd0BP7G2UyPDRQs_-8dPvTgQ78Tk6kcVGuMJjqNdr84 t.0:4723–5781 is only location verification. Live master EA226 LUNA_PRESEARCH_NOT_LOCATED, not completed source packet. No prior packet absence claimed from bounded search.
Question: which boundaries prevent a support Agent's draft/update from becoming unintended customer communication, concurrent data loss or unverified completion? Scope is Zendesk documentation plus independent historical SDK reports and executed Zenpy2.0.55 outgoing serialization. Not live customer support performance, legal advice or certification of other ticketing vendors.

## Confirmed
- C1 PRIVATE_DRAFT_BOUNDARY. Real SDK update with Comment(body='draft',public=False) produced ticket.comment.public=false. Omitting public produced no outgoing visibility field. Combined with S2 this means a draft must explicitly state intended visibility rather than relying on omission. Runtime verifies bytes, not server audience, routing or notification. Human approval should bind draft hash, requester/channel and public/private choice; classification and escalation do not imply permission to send a customer reply. This approval design is a proposal, not a built-in Zendesk guarantee.
C2 CONCURRENCY_GUARDS_MUST_REACH_EACH_REQUEST. Real Zenpy update included safe_update:true and updated_stamp:'2026-10-05T00:00:00Z' in the single ticket payload. That timestamp is artificial; production requires authoritative last read. S1 documents conflict handling; S3 is historical counterevidence to assuming a high-level SDK save is one guarded atomic action. Trace every affected endpoint and independently reconcile after partial failure. Our Zenpy fixture does not reproduce Ruby #420, prove its current fix, or test real409 enforcement.
C3 SUCCESS_RESPONSE_NOT_INTENDED_STATE. S4 is a bounded historical firsthand counterexample. The injected successful Zenpy response cannot prove a remote ticket really changed. Read back exact fields, public/private comment and actor/approver provenance; separate acknowledged request from completed outcome. If update timed out or a multipart save partly failed, mark outcomeunknown and reconcile before repeating comments or external messages.
C4 EMPTY_ARRAY_IS_AN_EXPLICIT_CHANGE. Real SDK Ticket(id123,tags=[]) emitted tags:[], rather than omitting tags. The server effect is untested. Do not replace the ticket's full tag set merely to classify it without an approved change set and concurrency review. Proposed rule: preserve unrelated human assignments/tags and re-evaluate intent after a stale-state conflict; no unconditional retry that overwrites the new state.
C5 ASYNC_AND_AUDIT_BOUNDARIES. S1 documents a distinction between accepted async job and available completed ticket, and between changed update and audit creation. A job must be reconciled to resulting ticket; absence of a newly created remote audit cannot be the only integration execution log. This is documented behavior, not runtime reproduction here.

## UNKNOWN
- EA-226-UNKNOWN-01: Unknown: actual tenant permission and brand/workflow/trigger, notification recipients,409 enforcement across endpoints, SDK retry behavior and side effects, current Ruby issue resolution, Zenpy #105 rootcause, idempotency/dedup per comment/create, current webhook/loop behavior, independent modern operations corpus, live safe sandbox comparison, actual escalation/answer quality. Supplemental task should acquire these without rewriting historical report as current defect. Stop customer send on wrong audience/account, missing approval or unresolved write; stop publication on vendor/version generalization or claiming offline fixture is real service execution. Independent :20 reviews claims/source dates and runtime limits, may require supplement before approving exact semantic scope. No self PASS.

## Evidence
- EVD-EA-226-URL-EC2CB7D759A7 (RESEARCH): S1 PROVIDER_SPEC, unversioned current read: — https://developer.zendesk.com/documentation/ticketing/managing-tickets/creating-and-updating-tickets/
- EVD-EA-226-URL-6447877A5EBE (RESEARCH): S2 PROVIDER_SPEC current read: — https://developer.zendesk.com/api-reference/ticketing/tickets/ticket_comments/
- EVD-EA-226-URL-995D6C4E25E3 (RESEARCH): S3 INDEPENDENT_FIRSTHAND_REPORT: — https://github.com/zendesk/zendesk_api_client_rb/issues/420
- EVD-EA-226-URL-3E80FE253464 (RESEARCH): S4 INDEPENDENT_FIRSTHAND_REPORT: — https://github.com/facetoe/zenpy/issues/105
- EVD-EA-226-URL-C2E80886F662 (RESEARCH): S4 INDEPENDENT_FIRSTHAND_REPORT: — https://github.com/facetoe/zenpy
- EVD-EA-226-URL-CD6CC7899CCA (RESEARCH): Companion folder: — https://drive.google.com/drive/folders/1a8Asw9ars7016YCuLfLSdZJMFQmigKdY
- EA-226-CURRENT-APPROVAL (RESEARCH): 現行本文の監査・revision対応
- EA-226-CURRENT-BODY-READBACK (IMPL): 現行本文の収録照合

## Failure / limits
wrong public/private state; stale assignment or tag replacement; misleading200/202; partial multi-request failure; timeout followed by duplicate public comment; ticket-to-automation-to-Agent loops; knowledge answer unsupported by cited customer context. SECURITY: untrusted ticket text/attachments are data, not tool authorization; bind account, brand, ticket and actor, minimize credentials and independently inspect exact endpoint permissions. PRIVACY: customer PII, incident attachments and internal notes require bounded model input and controlled logs; explicit draft visibility alone does not prove model/attachment confidentiality. AUDIT: own append-only approval and request/readback record, plus remote actor/audit when available; no self-approved audit status. COST: count draft inference, API/reconciliation calls, duplicate comments and human review separately; no fabricated quota or price. OPERABILITY: stable event/action correlation, retry budget, per-ticket serialization and loop-stop policy are proposed controls; safe_update is not exactly-once external-message delivery. AVAILABILITY: job completion, API response and customer-channel delivery are different stages; mark unknown until the required stage is verified.
## Failure / limits
Unknown: actual tenant permission and brand/workflow/trigger, notification recipients,409 enforcement across endpoints, SDK retry behavior and side effects, current Ruby issue resolution, Zenpy #105 rootcause, idempotency/dedup per comment/create, current webhook/loop behavior, independent modern operations corpus, live safe sandbox comparison, actual escalation/answer quality. Supplemental task should acquire these without rewriting historical report as current defect. Stop customer send on wrong audience/account, missing approval or unresolved write; stop publication on vendor/version generalization or claiming offline fixture is real service execution. Independent :20 reviews claims/source dates and runtime limits, may require supplement before approving exact semantic scope. No self PASS.
## Practice
文書に基づく製品仕様の確認日は元パケットの2026-10-05です。過去の利用者報告を現行製品全体の不具合へ一般化しません。2026-10-16に元の固定バージョンSDKと模擬通信の検査を再実行し、findingsとSDKソースハッシュが復旧済み結果と一致しました。製品の最新バージョン確認、実tenantの更新、通知、権限、競合制御、課金・配信保証の検証ではありません。

Companion folder: https://drive.google.com/drive/folders/1a8Asw9ars7016YCuLfLSdZJMFQmigKdY
## Practice
`zenpy_fixture.py` SHA-256 `6c86296499fc48f329866045f0f4bc876322e30f50110056dcbb837b001e9ea2`
## Practice
`zenpy_results.json` SHA-256 `fc3150aff56dc429439efc8fe7b498e9eddd9468be007a94b29c1c1abc26feab`
## PUBLIC_CLAIM
Customer Support／Ticketing API連携では、分類・回答草案・人への引継ぎ・顧客への送信・状態更新を別の操作として管理する。内部メモは公開範囲を明示し、承認した本文と対象を送信前に照合する。更新競合の制御は各リクエストの実際のペイロードで確認し、応答後もチケット状態を再読込する。古い利用者報告には、SDKの別リクエストによる部分変更や、HTTP200後に意図した変更が確認できなかった例がある。今回のZenpy2.0.55検査は送出ペイロードの検査であり、実顧客への通知・現行サーバーの競合制御・SDK全版の挙動を保証しない。

## SCOPE
Current directly read proposal Doc 1_9XrDkXlopnx39HlRa1YDO8yRvOEBXup2vvY6senU7s t.0:27850–28133 distinguishes Zendesk classification, draft, knowledge retrieval, escalation and ticket update; automated customer reply and human handoff must be separate. Retreat 1Vd0BP7G2UyPDRQs_-8dPvTgQ78Tk6kcVGuMJjqNdr84 t.0:4723–5781 is only location verification. Live master EA226 LUNA_PRESEARCH_NOT_LOCATED, not completed source packet. No prior packet absence claimed from bounded search.
Question: which boundaries prevent a support Agent's draft/update from becoming unintended customer communication, concurrent data loss or unverified completion? Scope is Zendesk documentation plus independent historical SDK reports and executed Zenpy2.0.55 outgoing serialization. Not live customer support performance, legal advice or certification of other ticketing vendors.

## EVIDENCE_TABLE
S1 PROVIDER_SPEC, unversioned current read: https://developer.zendesk.com/documentation/ticketing/managing-tickets/creating-and-updating-tickets/ ; locators asynchronous creation lines21–30, audit83–90, collisions138–162. Async202 may precede readable ticket; safe_update with last-read updated_stamp and409/UpdateConflict is documented. An unchanged update does not necessarily create audit metadata. Available. These are provider contracts, not observed tenant behavior.
S2 PROVIDER_SPEC current read: https://developer.zendesk.com/api-reference/ticketing/tickets/ticket_comments/ ; lines15–23,43,49–52. Comments are added through ticket create/update; publicfalse is internal note; omission retains visibility behavior specified by service. Author and authenticated updater differ. Available, current unversioned schema.
S3 INDEPENDENT_FIRSTHAND_REPORT: https://github.com/zendesk/zendesk_api_client_rb/issues/420 ; justinlang,2020-01-28, description154–178. Reporter saw409 while tags had already changed, tracing a separate tag POST lacking guards. Closed historical report; currently deployed SDK behavior and fix revision not verified. Vendor-hosted repository does not make reporter's firsthand evidence vendor marketing. Do not transfer this Ruby-client failure to Zenpy.
S4 INDEPENDENT_FIRSTHAND_REPORT: https://github.com/facetoe/zenpy/issues/105 ; skrud,2017-03-03, description160–209. Reported HTTP200 update without intended subject change and showed trace/audit. Root cause not established in inspected body; version/current prevalence unknown. Closed does not prove present bug or fixed behavior.
S5 AUTHOR_CODE: https://github.com/facetoe/zenpy ; installed distribution Zenpy2.0.55 (not asserted latest), zenpy/lib/api.py update/_put/_serialize, request.py CRUDRequest.put and api_objects. Exact executed source hashes in zenpy_results.json. Available local source; distribution wheel SHA reported by pip f06888c4008a9dd12aead32705b79c09006246b87f7335b02338af0d2e8c3a9d. Do not equate installed distribution to a separately checked repository commit.
S6 ACTUAL_SDK_RUNTIME: zenpy_fixture.py, zenpy_results.json. Real Ticket/Comment objects, CRUD update and SDK serializer run; only session.put replaced by finite artificial response, socket.create_connection denied. Placeholder account/token are fake. No actual HTTP/API/customer notification. Initial mock lacked callable __name__, then response.request metadata; fixture failures were corrected, final run passed. Those fixture failures are not SDK defects.

## ESTABLISHED / FINDINGS
C1 PRIVATE_DRAFT_BOUNDARY. Real SDK update with Comment(body='draft',public=False) produced ticket.comment.public=false. Omitting public produced no outgoing visibility field. Combined with S2 this means a draft must explicitly state intended visibility rather than relying on omission. Runtime verifies bytes, not server audience, routing or notification. Human approval should bind draft hash, requester/channel and public/private choice; classification and escalation do not imply permission to send a customer reply. This approval design is a proposal, not a built-in Zendesk guarantee.
C2 CONCURRENCY_GUARDS_MUST_REACH_EACH_REQUEST. Real Zenpy update included safe_update:true and updated_stamp:'2026-10-05T00:00:00Z' in the single ticket payload. That timestamp is artificial; production requires authoritative last read. S1 documents conflict handling; S3 is historical counterevidence to assuming a high-level SDK save is one guarded atomic action. Trace every affected endpoint and independently reconcile after partial failure. Our Zenpy fixture does not reproduce Ruby #420, prove its current fix, or test real409 enforcement.
C3 SUCCESS_RESPONSE_NOT_INTENDED_STATE. S4 is a bounded historical firsthand counterexample. The injected successful Zenpy response cannot prove a remote ticket really changed. Read back exact fields, public/private comment and actor/approver provenance; separate acknowledged request from completed outcome. If update timed out or a multipart save partly failed, mark outcomeunknown and reconcile before repeating comments or external messages.
C4 EMPTY_ARRAY_IS_AN_EXPLICIT_CHANGE. Real SDK Ticket(id123,tags=[]) emitted tags:[], rather than omitting tags. The server effect is untested. Do not replace the ticket's full tag set merely to classify it without an approved change set and concurrency review. Proposed rule: preserve unrelated human assignments/tags and re-evaluate intent after a stale-state conflict; no unconditional retry that overwrites the new state.
C5 ASYNC_AND_AUDIT_BOUNDARIES. S1 documents a distinction between accepted async job and available completed ticket, and between changed update and audit creation. A job must be reconciled to resulting ticket; absence of a newly created remote audit cannot be the only integration execution log. This is documented behavior, not runtime reproduction here.

## FAILURE
wrong public/private state; stale assignment or tag replacement; misleading200/202; partial multi-request failure; timeout followed by duplicate public comment; ticket-to-automation-to-Agent loops; knowledge answer unsupported by cited customer context. SECURITY: untrusted ticket text/attachments are data, not tool authorization; bind account, brand, ticket and actor, minimize credentials and independently inspect exact endpoint permissions. PRIVACY: customer PII, incident attachments and internal notes require bounded model input and controlled logs; explicit draft visibility alone does not prove model/attachment confidentiality. AUDIT: own append-only approval and request/readback record, plus remote actor/audit when available; no self-approved audit status. COST: count draft inference, API/reconciliation calls, duplicate comments and human review separately; no fabricated quota or price. OPERABILITY: stable event/action correlation, retry budget, per-ticket serialization and loop-stop policy are proposed controls; safe_update is not exactly-once external-message delivery. AVAILABILITY: job completion, API response and customer-channel delivery are different stages; mark unknown until the required stage is verified.

## 未確認事項と停止・確認条件
Unknown: actual tenant permission and brand/workflow/trigger, notification recipients,409 enforcement across endpoints, SDK retry behavior and side effects, current Ruby issue resolution, Zenpy #105 rootcause, idempotency/dedup per comment/create, current webhook/loop behavior, independent modern operations corpus, live safe sandbox comparison, actual escalation/answer quality. Supplemental task should acquire these without rewriting historical report as current defect. Stop customer send on wrong audience/account, missing approval or unresolved write; stop publication on vendor/version generalization or claiming offline fixture is real service execution. Independent :20 reviews claims/source dates and runtime limits, may require supplement before approving exact semantic scope. No self PASS.

## CURRENTNESS / TEST_PROFILE
文書に基づく製品仕様の確認日は元パケットの2026-10-05です。過去の利用者報告を現行製品全体の不具合へ一般化しません。2026-10-16に元の固定バージョンSDKと模擬通信の検査を再実行し、findingsとSDKソースハッシュが復旧済み結果と一致しました。製品の最新バージョン確認、実tenantの更新、通知、権限、競合制御、課金・配信保証の検証ではありません。

Companion folder: https://drive.google.com/drive/folders/1a8Asw9ars7016YCuLfLSdZJMFQmigKdY

- `zenpy_fixture.py` SHA-256 `6c86296499fc48f329866045f0f4bc876322e30f50110056dcbb837b001e9ea2`
- `zenpy_results.json` SHA-256 `fc3150aff56dc429439efc8fe7b498e9eddd9468be007a94b29c1c1abc26feab`

NEXT: /agent/start.json
STOP: This is a knowledge projection, not an execution order.