Urlicer API v1

Folders

List, create, rename, move and delete the folders your links are filed in.

A folder is where a link is filed. Folders can be nested up to five levels, every link belongs to at most one of them, and a link that is in none is unfiled. Filing changes nothing about how a link resolves: it is workspace organisation, not routing.

Folders are named by path, everywhere. Sending "folder": "Campaigns/Q4" when you create or update a link files it there, and the folders in that path are created if they are missing. Renaming, moving and deleting a folder name it the same way, with ?path=. The id in a response is there for your own records: the API never asks for it, so there is no number to guess and no way to name a folder that is not yours.

List folders

GET /api/v1/folders

The whole folder tree of the workspace the key belongs to, ordered by path.

Request
curl -X GET "https://urlicer.com/api/v1/folders" \
  -H "Authorization: Bearer url_live_YOUR_KEY"
Response
{
  "folders": [
    {
      "id": 41,
      "path": "Campaigns",
      "name": "Campaigns",
      "parentId": null,
      "depth": 1,
      "links": 3,
      "linksTotal": 131
    },
    {
      "id": 42,
      "path": "Campaigns/Q4",
      "name": "Q4",
      "parentId": 41,
      "depth": 2,
      "links": 128,
      "linksTotal": 128
    }
  ],
  "total": 2,
  "unfiled": 17
}
Response fields
Field Type Description
folders array Every folder in the workspace, sorted by path, so a parent always comes before its children and the list can be rendered as a tree by indenting it.
total integer How many folders the workspace has.
unfiled integer How many links are in no folder at all. List them with GET /api/v1/links?unfiled=1.
  • There is no paging: a workspace has tens or hundreds of folders, and half a tree would be no use to anyone.
  • Folders are a paid feature, reading them included. On a plan without folders every endpoint on this page answers 403 feature, and a workspace that downgrades keeps its folders and its filing untouched until it upgrades again.

Create a folder

POST /api/v1/folders

Make a folder, or get back the one already there. Sending the same path twice creates nothing the second time.

Body fields
Field Type Required Description
path string required, or name The whole path to make: "Campaigns/Q4/Email" creates all three levels, skipping any that already exist. Up to five levels deep.
name string required, or path One folder's name, when you know where it goes. At most 120 characters, and it cannot contain "/", because that is what separates levels.
parent string optional Used with name: the folder to create it in, by path. Leave it out, or send "", for the top level. A parent that does not exist answers 400 - use path to create a whole chain at once.
Request
curl -X POST "https://urlicer.com/api/v1/folders" \
  -H "Authorization: Bearer url_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"path": "Campaigns/Q4"}'
Response
{
  "id": 42,
  "path": "Campaigns/Q4",
  "name": "Q4",
  "parentId": 41,
  "depth": 2,
  "links": 0,
  "linksTotal": 0
}
Response fields
Field Type Description
id integer A stable number for the folder, unchanged by a rename or a move. Useful for matching a folder against your own records; the API itself never asks for it.
path string The full path from the top, with "/" between levels: "Campaigns/Q4/Email". This is how every endpoint names a folder: on a link, and as ?path= here.
name string Just this folder's own name, without its parents.
parentId integer or null The id of the folder this one sits in, or null at the top level - enough to rebuild the tree without parsing paths. Like id, it is reported, never asked for.
depth integer How deep it sits, counting itself: a top-level folder is 1, and 5 is the deepest a folder can be.
links integer Links filed directly in this folder, not counting its subfolders.
linksTotal integer Links in this folder and everything beneath it: what GET /api/v1/links?folder= returns, and the number the app shows on the folder. The same as links for a folder with no subfolders.
  • This is a find-or-create, and so is the folder field on a link: an import that runs every night creates the tree once and then keeps finding it. You never need a "does this folder exist" call.
  • Two requests racing on the same path end up with one folder, and both get it back. Names are compared case-insensitively within a level, so "Q4" and "q4" are the same folder.
  • Folders can be five levels deep. A path with more levels answers 400 validation and creates none of them.
  • Creating a folder does not move any links. File links with the folder field on POST or PATCH /api/v1/links.

Rename or move a folder

PATCH /api/v1/folders

Change a folder's name, the folder it sits in, or both. Its links and subfolders come with it.

Query parameters
Field Type Required Description
path string required The folder to change, by its current path: "Campaigns/Q4". A path that does not resolve answers 404.
Body fields
Field Type Required Description
name string optional A new name for this level. The rest of the path is unaffected.
parent string or null optional The folder to move it into, by path; null or "" moves it to the top level. Sending the field is what moves the folder, so a rename that leaves it out cannot move anything by accident.
Request
curl -X PATCH "https://urlicer.com/api/v1/folders?path=Campaigns/Q4" \
  -H "Authorization: Bearer url_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Q4 2026", "parent": "Campaigns"}'
Response
{
  "id": 42,
  "path": "Campaigns/Q4 2026",
  "name": "Q4 2026",
  "parentId": 41,
  "depth": 2,
  "links": 128,
  "linksTotal": 128
}
Response fields
Field Type Description
id integer A stable number for the folder, unchanged by a rename or a move. Useful for matching a folder against your own records; the API itself never asks for it.
path string The full path from the top, with "/" between levels: "Campaigns/Q4/Email". This is how every endpoint names a folder: on a link, and as ?path= here.
name string Just this folder's own name, without its parents.
parentId integer or null The id of the folder this one sits in, or null at the top level - enough to rebuild the tree without parsing paths. Like id, it is reported, never asked for.
depth integer How deep it sits, counting itself: a top-level folder is 1, and 5 is the deepest a folder can be.
links integer Links filed directly in this folder, not counting its subfolders.
linksTotal integer Links in this folder and everything beneath it: what GET /api/v1/links?folder= returns, and the number the app shows on the folder. The same as links for a folder with no subfolders.
  • Renaming changes the path of this folder and of everything beneath it, so a script that remembers paths should re-read them afterwards. Nothing else changes: the links stay filed exactly where they were.
  • A move is refused with 400 validation when it would put a folder inside itself or inside one of its own subfolders, when the destination already has a folder of that name, or when it would push part of the tree past five levels.
  • A path is always read inside your own workspace, so there is no id to guess and no way to name someone else's folder. A path that does not resolve answers 404, whatever the reason.

Delete a folder

DELETE /api/v1/folders

Remove a folder. Its links and subfolders move up to the folder above it; nothing is deleted with it.

Query parameters
Field Type Required Description
path string required The folder to delete, by path.
Request
curl -X DELETE "https://urlicer.com/api/v1/folders?path=Campaigns/Q4" \
  -H "Authorization: Bearer url_live_YOUR_KEY"
Response
{
  "success": true,
  "movedFolders": 2,
  "movedLinks": 128,
  "movedTo": "Campaigns"
}
Response fields
Field Type Description
success boolean True when the folder was deleted.
movedFolders integer How many subfolders moved up one level.
movedLinks integer How many links moved up with them.
movedTo string or null The path everything moved to, or null when the deleted folder was at the top level and its contents are now unfiled.
  • Deleting a folder never deletes a link. To delete the links as well, list them with GET /api/v1/links?folder=..., then delete each one.
  • Deleting the folder a path names deletes only that folder. Its subfolders keep their own links and simply move up one level.
  • A subfolder whose name is already taken in the destination keeps its links and is given a numbered name, rather than the delete being refused. You asked to delete a folder, not to resolve names.

There is no "add link to folder" endpoint. A link carries its folder, so you set it where you set everything else about the link:

  • On create. POST /api/v1/links with "folder": "Campaigns/Q4" creates the link already filed.
  • On a batch. POST /api/v1/links/bulk takes one folder for the whole batch.
  • Later. PATCH /api/v1/links/{code} with a different folder moves the link, and "folder": null unfiles it. Leaving the field out of a PATCH never moves anything.
  • Reading back. Every link response carries folder as a path, and GET /api/v1/links?folder=Campaigns lists a folder and its subfolders. ?unfiled=1 lists the links in no folder.

Moves through the API are recorded in your workspace's audit trail, naming the key that made them, exactly as a move in the app names the person who made it.

Paths, names and case

A path is the folder names from the top, separated by /: Campaigns/Q4/Email. A folder name can never contain a slash, so a path always splits the same way, and the path in a response is exactly the value you can send back. Spaces around a separator are ignored, so Campaigns / Q4 and Campaigns/Q4 are the same folder.

Names are compared without regard to case within a level, so you cannot end up with Q4 beside q4. Case is preserved as you first typed it.

Creating by path is forgiving, because it makes what is missing. Reading by path is strict: the folder filter on a listing resolves the whole path or answers 400, so a renamed folder fails loudly instead of silently listing your whole workspace.

Deleting never loses links

Deleting a folder moves its links and its subfolders up to the folder above it, and tells you how many of each moved and where to. A top-level folder's contents become unfiled. Nothing is deleted except the folder itself, so a delete can always be walked back by re-creating the folder and filing the links again.

Deleting a link is unaffected by any of this: see the links reference.

Plans

Folders are part of the paid plans, and that includes reading them: on a plan without folders every endpoint on this page answers 403 with "key": "LinkFolders", as does creating or moving a link into a folder. Titles and notes on a link are free on every plan.

If a workspace downgrades, nothing is lost. The folders stay, the links stay filed, and the tree comes back as it was when the workspace upgrades again.