NUACOM API

Calls

Call Tags

Call tags are labels an account defines once, in a catalogue, and then assigns to calls so that call history can be filtered and reported by outcome. The catalogue is a tree up to five levels deep: a tag has a name, a color, an availability (all calls, inbound only or outbound only), an optional parent and optional visibility rules that limit it to some extensions or departments. This group holds the catalogue endpoints under /v3/call-tags, the assignment endpoints GET /v2/call-tags and POST /v2/add-call-tag, and an older delete. Call rows carry their tags in extra.call_tags (see Call Logs); rules that make tagging mandatory after a call are in After Call Work.

Workflow (what the portal does)

  1. Tag picker: GET /v3/call-tags/all-parent-child answers every tag the user may see, parents and children alike, as one flat array in catalogue order; build the tree client-side on parent_id. descendants_count is always 0 on this endpoint.
  2. Catalogue page: GET /v3/call-tags with page and perPage (both required; perPage is 15, 25, 50, 100, or -1 for all) lists the top-level tags only, each with its descendants_count and visibility rules. Filters: filter[name] and filter[color] (partial match), filter[available_for] (2 inbound or 3 outbound; tags available for all calls are always included). A paginated answer is {"data": [tags], "links": {…}, "meta": {…}} with meta.total and meta.last_page; perPage=-1 answers a plain array.
  3. One tag and its children: GET /v3/call-tags/{callTag} answers the tag with descendants, its direct children, each with their own descendants_count; available_for in the query limits the children the way the list filter does. Account admins also get the tag's visibility.
  4. Create (account admin): POST /v3/call-tags with name (up to 20 characters), color (#rgb or #rrggbb; the key is required but may be null) and, optionally, parent_id, available_for (1 all calls, the default; 2 inbound; 3 outbound), visible_to (a list of up to 100 entries, each {"type": 1, "allowed_id": <extension number>} or {"type": 2, "allowed_id": <department id>}) and order_column (the position in the catalogue, from 1; 0 or omitted appends the tag at the end). Answers 201 with the tag.
  5. Update (account admin): PUT /v3/call-tags/{callTag} with the same body. name and color are saved on every call; parent_id, available_for, visible_to and order_column change only when the key is present. "parent_id": null promotes a child to the top level, "visible_to": [] (or null) removes every visibility rule, and an omitted visible_to keeps them. Answers 202 with the tag.
  6. Assign to a call: POST /v2/add-call-tag with call_id (the row's call_id, sip_call_id or original_sip_call_id, as a string) and tag_info_id (the catalogue id). Answers 204; assigning a tag the call already has is a no-op. A new assignment is pushed to the account's CRM integrations and fires the tag_added webhook (see Integrations).
  7. Read a call's tags: GET /v2/call-tags?callIDs[]=… with the row's call_id, sip_call_id and original_sip_call_id (an array, or one comma-separated string). It answers the account's whole catalogue, parents and children, in id order, with the stored fields id, tag_name, tag_color, parent_id, available_for, order_column, plus assigned (1 or 0) for that call. Without callIDs it answers 406.
  8. Delete (account admin): DELETE /v3/call-tags/{callTag} removes the tag with its whole subtree, every assignment of those tags on calls and their CRM tag mappings (ActiveCampaign, HubSpot); it answers 204, or 404 for a tag of another account. DELETE /v2/tags/{id} is the older form: it detaches the one tag from every call (one tag_removed webhook per call) and deletes it, without the subtree and CRM clean-up, so use it only for a tag that has no children.
# A catalogue tag for inbound calls, visible to extension 101 only
curl -X POST https://api.api-nuacom.com/v3/call-tags \
  -H 'Authorization: Bearer YOUR_API_KEY' -H 'Content-Type: application/json' \
  -d '{"name":"Callback","color":"#ff5733","available_for":2,"visible_to":[{"type":1,"allowed_id":101}]}'
# → 201 {"id":42,"name":"Callback","color":"#ff5733","available_for":2,"descendants_count":0,"visibility":[{"type":1,"allowed_id":101}],"order_column":7,"parent_id":null}

# Assign it to a call
curl -X POST https://api.api-nuacom.com/v2/add-call-tag \
  -H 'Authorization: Bearer YOUR_API_KEY' -H 'Content-Type: application/json' \
  -d '{"call_id":"1761640800.123","tag_info_id":42}'
# → 204

Reading a tag

Field Meaning
id The catalogue id; it is the tag_info_id you assign with, and the tags filter value of the call-log list
name, color The label and its hex color (tag_name, tag_color on GET /v2/call-tags)
available_for 1 all calls, 2 inbound only, 3 outbound only
parent_id null for a top-level tag, otherwise the parent's id
order_column The position in the catalogue, from 1; every list is sorted by it
descendants_count, descendants The number of direct children, and the children themselves where the endpoint loads them
visibility The visibility rules: type 1 with an extension number, or 2 with a department id. No rules means visible to everyone

Roles and access

  • Reading the catalogue, reading a call's tags and assigning tags: any authenticated user. The /v3/call-tags reads hide restricted tags from non-admin users: a user sees the tags without visibility rules plus those whose rules name their extension or one of their departments, and GET /v3/call-tags/{callTag} answers 404 for a tag they may not see. GET /v2/call-tags applies no visibility filter. Account admins see every tag.
  • Creating, updating and deleting catalogue tags: account admin only. The /v3/call-tags writes answer 403 for any other user; DELETE /v2/tags/{id} answers 403 with the body "Forbidden".

Pitfalls

  • Two different things are called "call tags": GET /v3/call-tags is the catalogue, GET /v2/call-tags is the assignment state of one call; POST /v3/call-tags creates a catalogue entry, POST /v2/add-call-tag assigns one. There is no POST /v2/call-tags: that path is redirected to the catalogue create, so a body meant for an assignment is validated as a new tag.
  • GET /v2/call-tags reads one call: it takes the first call that matches any id you pass and answers that call's assignments. Pass the three ids of one row, not the ids of several calls.
  • tag_info_id is not checked against the catalogue: an unknown id, or another account's, answers 204 and creates an assignment that GET /v2/call-tags never shows.
  • There is no endpoint to remove one tag from one call. The portal does that in the browser; through the API the only removals are the catalogue deletes, which detach the tag from every call.
  • page and perPage are required on GET /v3/call-tags (422 without them); sort is accepted but ignored; an unknown filter[...] key answers 400.
  • A tag can be at most five levels deep, cannot be its own parent and cannot be moved under one of its own descendants (422). parent_id must be a tag of the account.
  • A visible_to entry must name something the account owns, an extension number for type 1 or a department id for type 2 (422); a tag whose rules match nobody disappears for every non-admin user.
  • name over 20 characters, or a color that is not a hex code, answers 422. Both are required on every PUT, not only on create.
  • DELETE /v2/tags/{id} answers 204 for an id that does not exist. DELETE /v3/call-tags/{callTag} sends no tag_removed webhook for the assignments it removes; only the v2 delete does.