---
title: "Save a URL"
method: POST
path: "/v1/bookmarks"
tags: ["Bookmarks"]
---

# Save a URL

`POST /v1/bookmarks`

## Request

- Base URL: `https://stashr.me`
- URL: `https://stashr.me/v1/bookmarks`
- Auth: HTTP bearer

Fetch a public URL and save its metadata as a web bookmark. Idempotent: a URL already in the library returns the existing bookmark with 200 instead of creating a duplicate; a new save returns 201. Requires the write scope.

## Request body

- object
  - `url` string, uri, required: Public http(s) URL to save

## Response `200`

The URL was already saved; the existing bookmark is returned

- object
  - `data` SaveBookmarkResult, required
    - `bookmark` Bookmark, required
      - `author` Author, nullable
        - `avatarUrl` string, nullable
        - `displayName` string, nullable
        - `profileUrl` string, nullable
        - `username` string, required
      - `capturedAt` string, date-time, required
      - `content` object[], required: Portable Text blocks holding the full body
      - `contentCreatedAt` string, date-time, nullable
      - `contentType` string, required: One of: repo, image, post, video, comment, article, page, snippet
      - `deletedAt` string, date-time, nullable
      - `id` string, uuid, required
      - `isFavorite` boolean
      - `media` Media[], required
        - `altText` string, nullable
        - `duration` number, nullable
        - `height` integer, nullable
        - `ref` string, required: Stable media ref usable with the media preview
        - `storedUrl` string, nullable
        - `thumbUrl` string, nullable: 800px webp derivative of storedUrl, when generated. Prefer it for previews/grids; storedUrl is the full-resolution archive.
        - `type` 'image' | 'video', required
        - `url` string, required
        - `width` integer, nullable
      - `note` string, nullable
      - `platform` 'github' | 'instagram' | 'reddit' | 'tiktok' | 'twitter' | 'web' | 'youtube', required: Platform id. X/Twitter is "twitter".
      - `platformId` string
      - `tags` Tag[], required
        - `color` string, required
        - `count` integer, required: Active bookmarks currently carrying this tag
        - `id` string, uuid, required
        - `name` string, required
      - `title` string, nullable: Present on titled content such as X articles
      - `url` string, uri, required
    - `created` boolean, required: true when a new bookmark was created (201), false when the URL was already in the library (200)

## Other responses

- `201`: Bookmark created
- `400`: Malformed request (error.code bad_request or invalid_json)
- `401`: Missing, invalid, or expired credentials (error.code unauthorized)
- `402`: A Pro plan or active trial is required (error.code payment_required)
- `403`: The credential lacks the required scope (error.code forbidden)
- `404`: The resource does not exist or belongs to another account (error.code not_found)
- `422`: Validation failed; error.details.issues lists the fields (error.code validation_error)
- `429`: Too many requests (error.code rate_limited); wait Retry-After seconds, also given as error.retryAfterMs
- `500`: Something failed on Stashr's side (error.code internal_error); retryable

---

[API](https://skmtc.dev/stashr/apis/stashr-api.md) · [All operations](https://skmtc.dev/stashr/apis/stashr-api/llms.txt) · [OpenAPI document](https://skmtc.dev/stashr/apis/stashr-api/revisions/bcab186e0646?raw)
