@@ -115,7 +115,56 @@ for _, row := range res.Results {
115115}
116116```
117117
118- ` BulkDelete ` , ` BulkUpdateExpiry ` , and ` BulkMoveDomain ` follow the same shape.
118+ ` BulkDelete ` , ` BulkUpdateExpiry ` , ` BulkMoveDomain ` , and ` BulkUpdateTags ` follow
119+ the same shape.
120+
121+ ## Tags
122+
123+ Tags are account-wide labels with a color and an icon. A link carries up to
124+ ten of them, by id:
125+
126+ ``` go
127+ tag , err := client.CreateTag (ctx, spoo.CreateTagParams {Name: " launch" , Color : " violet" })
128+
129+ link , err := client.Shorten (ctx, spoo.ShortenRequest {
130+ LongURL : " https://example.com/launch" ,
131+ TagIDs : []string {tag.ID },
132+ })
133+
134+ // on update the list replaces the stored one; spoo.Null clears it
135+ _, err = client.UpdateURL (ctx, link.ID , spoo.UpdateURLParams {
136+ TagIDs : spoo.Set ([]string {tag.ID }),
137+ })
138+ ```
139+
140+ Filter the link list by tag id or name, and pick whether a link needs any or
141+ all of them:
142+
143+ ``` go
144+ page , err := client.ListURLs (ctx, spoo.ListURLsOptions {
145+ TagNames : []string {" launch" , " q3" },
146+ TagsMatch : " all" ,
147+ })
148+ ```
149+
150+ Tag or untag up to 100 links at once; the result has the same per-item shape
151+ as the other bulk operations:
152+
153+ ``` go
154+ res , err := client.BulkUpdateTags (ctx, ids, spoo.BulkTagChange {Add: []string {tag.ID }})
155+ ```
156+
157+ Stats and exports take ` tag ` (names) and ` tag_id ` filters on the aggregate
158+ routes, covering the whole click history of the tagged links:
159+
160+ ``` go
161+ stats , err := client.Stats (ctx, spoo.StatsQuery {
162+ Filters : map [string ][]string {" tag" : {" launch" }},
163+ })
164+ ```
165+
166+ ` ListTags ` , ` UpdateTag ` , and ` DeleteTag ` round out the set. Deleting a tag
167+ removes it from every link and reports how many were touched.
119168
120169## Stats and exports
121170
@@ -243,8 +292,9 @@ file, or database, and rotated tokens persist through it.
243292## Scope
244293
245294The SDK covers the v1 data plane end to end: shortening, link management,
246- claiming, bulk operations, stats, exports, public stats and previews, the
247- emoji alias policy, identity (` Me ` ), and the Sign in with Spoo device flow.
295+ claiming, tags, bulk operations, stats, exports, public stats and previews,
296+ the emoji alias policy, identity (` Me ` ), and the Sign in with Spoo device
297+ flow.
248298Deliberately out of scope: API key management, health checks, the contact
249299endpoint, profile management, and all legacy v0 routes. Anything the API
250300grows before the SDK does is reachable through the raw request methods
@@ -260,7 +310,9 @@ below.
260310| ` UpdateURL ` , ` SetURLStatus ` | ` PATCH /api/v1/urls/{id} ` , ` PATCH /api/v1/urls/{id}/status ` |
261311| ` DeleteURL ` , ` DeleteURLsByDomain ` | ` DELETE /api/v1/urls/{id} ` , ` DELETE /api/v1/urls?domain= ` |
262312| ` ClaimURLs ` | ` POST /api/v1/urls/claim ` |
263- | ` BulkDelete ` , ` BulkUpdateStatus ` , ` BulkUpdateExpiry ` , ` BulkMoveDomain ` | ` POST /api/v1/urls/bulk/* ` |
313+ | ` BulkDelete ` , ` BulkUpdateStatus ` , ` BulkUpdateExpiry ` , ` BulkMoveDomain ` , ` BulkUpdateTags ` | ` POST /api/v1/urls/bulk/* ` |
314+ | ` ListTags ` , ` CreateTag ` | ` GET /api/v1/tags ` , ` POST /api/v1/tags ` |
315+ | ` UpdateTag ` , ` DeleteTag ` | ` PATCH /api/v1/tags/{id} ` , ` DELETE /api/v1/tags/{id} ` |
264316| ` Stats ` , ` LinkStats ` , ` StatsByAlias ` | ` GET /api/v1/stats ` , ` GET /api/v1/stats/links/{id} ` |
265317| ` PublicStats ` , ` PublicPreview ` | ` GET or POST /api/v1/public/stats/{code} ` , ` GET /api/v1/public/preview/{code} ` |
266318| ` Export ` , ` ExportLink ` | ` GET /api/v1/export ` , ` GET /api/v1/export/links/{id} ` |
0 commit comments