Skip to content

Zammad Integration

The Zammad integration is a read-only connection for service-desk reporting. It supports Zammad Cloud and self-hosted Zammad instances that are reachable from the public internet over HTTPS.

Private or firewall-only Zammad instances are not supported in this release. The Zammad integration does not run through the Resplendent Sync Agent.

You need:

  • A dedicated Zammad service user. Avoid tying the connection to a person’s account.
  • Agent access to every Zammad group whose tickets should be available to Resplendent.
  • The ticket.agent permission for core ticket access.
  • The user_preferences.access_token permission while creating the token.
  • A public Zammad Instance URL with a certificate trusted by standard public certificate authorities.

The integration never creates, updates, or deletes records in Zammad.

Give the service user’s role only the permissions needed for the Datasets you plan to sync.

Permission Required? What it enables
ticket.agent Yes Core ticket, tag, user, organization, article, time-accounting, state, and priority access
admin.group Optional Groups Dataset
admin.sla Optional SLAs Dataset
admin.role Optional Roles Dataset

The service user also needs read access to the appropriate Zammad groups. Zammad only returns records that the token user is allowed to see.

Missing an optional permission does not break the connection or other Datasets. Resplendent shows a warning on the affected Groups, SLAs, or Roles Dataset instead.

You do not need admin.object. Custom fields returned by the normal Tickets, Users, and Organizations APIs are discovered automatically.

See Zammad’s documentation for the current permission reference and group access levels.

  1. In Zammad, open Admin → Manage → Roles.
  2. Create a role for Resplendent and grant ticket.agent.
  3. Add admin.group, admin.sla, or admin.role only if you want the corresponding optional Dataset.
  4. Give the role read access to the Zammad groups that should be included in reporting.
  5. Create or select a dedicated service user and assign the role.

If the service user cannot open a ticket in the Zammad interface, its access token will not be able to sync that ticket either.

  1. Sign in to Zammad as the service user.
  2. Open the user’s profile from the avatar menu and select Token Access.
  3. Create a token named Resplendent Data.
  4. Select ticket.agent and any optional permissions you chose above.
  5. Set an expiration date that matches your credential-rotation policy.
  6. Copy the token when Zammad displays it. Zammad displays a newly created token only once.

Resplendent uses Zammad’s HTTP access-token authentication. Do not provide a Zammad password or an OAuth token. For more detail, see Zammad’s API authentication guide and access-token reference.

  1. In Resplendent Data, go to Settings → Integrations.
  2. Find Zammad and select Connect.
  3. Enter the two fields shown in the setup form:
    • Instance URL: the public HTTPS root of your Zammad instance, such as https://support.example.com. Do not include /api/v1, credentials, a query string, or a fragment.
    • Access Token: the token created for the service user.
  4. Test and save the connection.
  5. Select the Datasets and columns you want to sync.

The connection test makes a small Tickets request. A successful test proves that the token is valid and can read the core ticket API. Each selected Dataset then runs independently and reports its own permission or response error.

The Instance URL must remain on the same HTTPS origin if Zammad redirects an API request. Its DNS records must resolve only to public network addresses. Private, loopback, link-local, and embedded-credential destinations are rejected.

These are the defaults requested by the integration. Your Resplendent subscription tier can impose a longer effective minimum interval.

Dataset Core or optional Daytime sync Nightly replacement
Tickets Core Every 5 minutes, incremental Yes
Ticket Articles Core Every 5 minutes, incremental Yes
Ticket Tags Core Every 5 minutes, incremental Yes
Time Accounting Core Every 15 minutes, incremental Yes
Users Core Every 60 minutes, incremental Yes
Organizations Core Every 60 minutes, incremental Yes
Ticket States Core Every 1,440 minutes, full Yes
Ticket Priorities Core Every 1,440 minutes, full Yes
Groups Optional; admin.group Every 1,440 minutes, full Yes
SLAs Optional; admin.sla Every 1,440 minutes, full Yes
Roles Optional; admin.role Every 1,440 minutes, full Yes

Initial history is downloaded in bounded, resumable batches. Daytime incremental reads use a small timestamp overlap and primary-key deduplication so records sharing the same update time are retained. Requests use bounded ticket-level concurrency so large instances do not create an unbounded request burst.

During the day, changed records are added or updated. Hard deletions converge through independent nightly replacements:

  1. Tickets replaces itself from the complete current Tickets endpoint.
  2. Ticket Articles separately replaces itself from the complete current Ticket Articles endpoint.
  3. Ticket Tags separately replaces itself by reading the complete current tag list for every visible ticket.
  4. Time Accounting separately replaces itself from the complete current Time Accounting endpoint.

The Datasets do not inspect or modify one another. Their nightly runs can finish at different times, so a temporary cross-Dataset mismatch is expected after a source deletion. Each Dataset converges when its own next replacement succeeds. If one replacement fails or is interrupted, Resplendent keeps that Dataset’s previous complete data without affecting any other Dataset.

A closed ticket is not a deleted ticket. Closed tickets, inactive users, inactive organizations, and inactive lookup values remain in their Datasets while Zammad continues to return them. Only absence from a completed authoritative source snapshot is treated as a hard deletion.

Ticket tag changes touch their related ticket in Zammad. Daytime Ticket Tags syncs therefore fetch the current tag associations for tickets inside the timestamp overlap window. A removed or renamed association can remain temporarily until Ticket Tags completes its own nightly replacement; it does not inspect or mutate the stored Tickets Dataset.

Ticket Tags contains one row per ticket-and-tag association. Each row has a deterministic relationship ID, the source Ticket ID, the tag text, and the related ticket’s update timestamp. The Ticket ID and tag columns link to the corresponding ticket in Zammad.

Tag text is limited to 32,000 Unicode characters. Longer values retain a visible ellipsis inside the limit and set tag_truncated; original_tag_length records the source length. The relationship ID is derived from the complete source value, so truncation cannot merge two distinct tags.

Ticket Articles includes both public replies and internal notes that the service user is allowed to see. The internal column distinguishes the two. Restrict the service user’s group access and select Dataset columns deliberately because internal notes may contain sensitive information.

Article content is selectable rather than mandatory:

  • body contains bounded source content.
  • body_text contains a safely derived plain-text representation for search and analysis.
  • body_truncated and original_body_length describe truncation of body.
  • body_text_truncated and original_body_text_length describe truncation of body_text.

Both content columns have a limit of 32,000 Unicode characters. When content exceeds the limit, Resplendent keeps a visible ellipsis within the 32,000-character value and sets the corresponding truncation flag.

If you do not want message content stored in Resplendent, omit body and body_text when selecting Ticket Articles columns. You can still analyze metadata such as direction, sender, recipient, subject, content type, timestamps, and whether an article is internal.

Attachment handling is metadata-only. Resplendent can retain attachment ID, filename, size, content type, and attachment count. The Ticket Articles Dataset does not create an attachment URL or link column in this release. It does not download or store attachment files, inline images, base64 payloads, or other attachment contents. Remote HTML is parsed as text without running scripts, loading embedded resources, or rendering remote content.

Each API request has one 30-second end-to-end deadline covering DNS resolution, validated-address failover, redirects, retry delays, and response streaming, with at most four attempts inside that deadline. JSON response bodies are streamed through a 16 MiB limit before decoding. For throttling and transient Zammad server failures, Resplendent honors a numeric Retry-After value within the remaining deadline and the 30-second delay cap. When that header is absent or invalid, it uses bounded exponential backoff with jitter.

After the bounded attempts are exhausted, the sync stops with an actionable rate-limit, remote-server, or network error. A later scheduled sync can retry without replacing a complete Dataset with partial data.

Error category What it means What to do
Invalid credentials Zammad rejected the Access Token, usually with HTTP 401. Create or rotate the service user’s API access token, then update Access Token in Resplendent. Do not use a password or OAuth bearer token.
Missing core permission The token cannot read Tickets and the connection reports that ticket.agent is required. Add ticket.agent to the service user’s role and token, confirm group read access, then test again.
Missing optional permission Groups, SLAs, or Roles shows a Dataset warning naming admin.group, admin.sla, or admin.role. Add only that permission if the Dataset is needed. Otherwise leave the optional Dataset unselected. Core syncs continue.
Unsafe URL The URL is not HTTPS, contains credentials/query/fragment data, resolves to a non-public address, or redirects to another origin. Enter the public root URL only. Private-network and firewall-only instances are unsupported in this release.
TLS failure The certificate could not be validated. Install a certificate with a complete chain trusted by public certificate authorities. Certificate verification cannot be disabled.
Network failure DNS did not resolve, the public host could not be reached, or requests timed out after bounded retries. Confirm public DNS, firewall rules, and Zammad availability from outside the Zammad network.
Throttling Zammad kept returning HTTP 429 after Resplendent honored bounded retry delays. Reduce competing API traffic, review Zammad capacity, and let the next scheduled sync retry.
Unsupported response shape Zammad returned invalid JSON, a non-array Dataset response, or fields that do not match the supported schema. Record the Dataset name, Zammad version, timestamp, and safe error text, then contact support. Do not send the response body if it contains ticket content.
Transient Zammad failure Zammad kept returning HTTP 5xx after bounded retries. Check Zammad health and server logs, then retry after the incident. Existing complete Dataset data remains available.

Share the affected Dataset, approximate timestamp, Zammad version, Resplendent source identifier, and the exact safe error category. Never share the Access Token, an Authorization header, article bodies, attachment contents, or a raw API response containing customer data.

  • The Access Token is stored through Resplendent’s encrypted credential-key path and is not returned in visible connection metadata.
  • API requests are read-only and keep the Authorization header on the configured origin.
  • User-facing errors describe the failure category without copying Zammad response bodies.
  • Operational sync logs contain bounded identifiers and counts, not article bodies or attachment contents.
  • Custom fields keep their stable Zammad API names. Sparse values become null, and nested values are serialized deterministically.