Glasp API

Welcome to the Glasp API reference. This RESTful API allows developers to integrate with the Glasp platform to programmatically export and create highlights, among other features.

Highlight Export

Retrieve your Glasp highlights with optional filtering and pagination.

GEThttps://api.glasp.co/v1/highlights/export

Authentication

Bearer token in header. Get token from settings.

Authorization: BearerYOUR_ACCESS_TOKEN

Rate Limiting

100 requests/minute. Exceeding returns 429.

Query Parameters

Optional query parameters for pagination and filtering.

ParameterTypeRequiredDescription
pageCursorstringNoPagination cursor from previous response.
updatedAfterstringNoISO date string to get highlights updated after this date.

Response

  • Status code: 200
  • Response object containing highlights and pagination info.
Example Response
{
  "count": 1,
  "nextPageCursor": "2024-01-06T12:00:00Z",
  "results": [
    {
      "id": "page123",
      "title": "Example Article",
      "author": "Example Author",
      "thumbnail_url": "https://example.com/thumbnail.jpg",
      "url": "https://example.com/article",
      "glasp_url": "https://glasp.co/user/p/page123",
      "domain": "example.com",
      "category": "article",
      "document_note": "Important article about...",
      "summary": "This article discusses...",
      "tags": ["tech", "api"],
      "is_favorite": true,
      "created_at": "2024-01-06T12:00:00Z",
      "updated_at": "2024-01-06T12:00:00Z",
      "highlights": [
        {
          "id": "highlight123",
          "text": "This is a highlighted text",
          "note": "My note about this highlight",
          "color": "yellow",
          "highlighted_at": "2024-01-06T12:00:00Z",
          "created_at": "2024-01-06T12:00:00Z",
          "updated_at": "2024-01-06T12:00:00Z",
          "url": "https://example.com/article",
          "location": null,
          "location_type": "time_offset",
          "highlight_url": ""
        }
      ]
    }
  ]
}
Response Interface
interface HighlightExportResponse {
  count: number;
  nextPageCursor: string | null;
  results: {
    id: string;
    title: string;
    author: string;
    thumbnail_url: string;
    url: string;
    glasp_url: string;
    domain: string;
    category: "article" | "video" | "tweet" | "pdf" | "book"
    document_note: string | null;
    summary: string;
    tags: string[];
    is_favorite: boolean;
    created_at: string; // ISO date string
    updated_at: string; // ISO date string
    highlights: {
      id: string;
      text: string;
      note: string;
      color: "pink" | "yellow" | "blue" | "green"
      highlighted_at: string; // ISO date string
      created_at: string; // ISO date string
      updated_at: string; // ISO date string
      url: string;
      location: number | null; // YouTube timestamp in seconds
      location_type: "page" | "location" | "time_offset";
      highlight_url: string; // unique URL for the highlight
    }[];
  }[];
}

Example Request (JavaScript)

const token = "XXX"; // use your access token here

async function getAllHighlights(updatedAfter = null) {
  let allHighlights = [];
  let nextPageCursor = null;

  do {
    const queryParams = new URLSearchParams();
    if (nextPageCursor) {
      queryParams.append("pageCursor", nextPageCursor);
    }
    if (updatedAfter) {
      queryParams.append("updatedAfter", updatedAfter);
    }
    try {
      const response = await fetch(
        `https://api.glasp.co/v1/highlights/export?${queryParams.toString()}`,
        {
          headers: {
            Authorization: `Bearer ${token}`,
          },
        }
      );
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const data = await response.json();
      if (data.results && data.results.length > 0) {
        const highlights = data.results.map((result) => result);
        allHighlights = allHighlights.concat(highlights);
      }
      nextPageCursor = data?.nextPageCursor || null;
      if (!nextPageCursor) {
        break;
      }
    } catch (error) {
      console.error("Error fetching highlights:", error);
      break;
    }
  } while (nextPageCursor);
  return allHighlights;
}

// Get all of a user's highlights from all time
const allHighlights = await getAllHighlights();

// If you want to get new highlights updated since your last fetch, do this:
const lastFetchedAt = new Date(Date.now() - 24 * 60 * 60 * 1000);
const newHighlights = await getAllHighlights(lastFetchedAt.toISOString());

Highlight Create

Create new highlights in your Glasp account. Each highlight must include at least title, url, and text.

POSThttps://api.glasp.co/v1/highlights/create

Authentication

Bearer token in header. Get token from settings.

Authorization: BearerYOUR_ACCESS_TOKEN

Rate Limiting

15 requests/minute. Exceeding returns 429.

Query Parameters

Array of highlights to create. Each highlight must include at least title, url, and text. Max 100 highlights per request.

ParameterTypeRequiredDescription
titlestringYesTitle of the source (max 512 chars)
urlstringYesURL of the source (max 2048 chars)
textstringYesThe highlight text (max 8192 chars)
authorstringNoAuthor of the source (max 512 chars)
thumbnail_urlstringNoThumbnail image URL (max 2048 chars)
colorenumNoHighlight color (one of: pink, yellow, blue, green; default: pink)
notestringNoHighlight note (max 8192 chars)
tagsstring[]NoTags for the highlight (array of up to 5 strings, each max 25 chars)
locationnumberNoHighlight's location in the source content. For videos or podcasts, this refers to the start time in seconds. For books, it could be the page or line number.
location_typeenumNoOne of: page, location, time_offset (default: time_offset). This is mainly for videos, podcasts, and books.
highlighted_atstringNoWhen the highlight was made (ISO date string)
highlight_urlstringNoUnique URL for the specific highlight (eg. a concrete tweet in a thread or a podcast snippet). Use this only if it differs from the main source URL.

Response

  • Status code: 200
  • Array of created highlights.
Example Response
[
  {
    id: "page123",
    title: "Example Domain",
    author: "Example Author",
    thumbnail_url: "https://example.com/thumbnail.jpg",
    url: "https://example.com/",
    glasp_url: "https://glasp.co/user/p/page123",
    domain: "example.com",
    category: "article",
    document_note: "",
    summary: "",
    tags: ["Test", "Example"],
    is_favorite: false,
    created_at: "2024-01-06T12:00:00Z",
    updated_at: "2024-01-06T12:00:00Z",
    highlights: [
      {
        id: "highlight123",
        text: "This domain is for use in illustrative examples in documents.",
        note: "My note about this highlight",
        color: "yellow",
        highlighted_at: "2024-01-06T12:00:00Z",
        created_at: "2024-01-06T12:00:00Z",
        updated_at: "2024-01-06T12:00:00Z",
        url: "https://example.com/",
        location: null,
        location_type: "time_offset",
        highlight_url: "",
      },
    ],
  },
]
Response Interface
interface HighlightCreateResponse {
  id: string;
  title: string;
  author: string;
  thumbnail_url: string;
  url: string;
  glasp_url: string;
  domain: string;
  category: "article" | "video" | "tweet" | "pdf" | "book";
  document_note: string | null;
  summary: string;
  tags: string[];
  is_favorite: boolean;
  created_at: string; // ISO date string
  updated_at: string; // ISO date string
  highlights: {
    id: string;
    text: string;
    note: string;
    color: "pink" | "yellow" | "blue" | "green";
    highlighted_at: string; // ISO date string
    created_at: string; // ISO date string
    updated_at: string; // ISO date string
    url: string;
    location: number | null; // YouTube timestamp in seconds
    location_type: "page" | "location" | "time_offset";
    highlight_url: string; // unique URL for the highlight
  }[];
}[]

Example Request (JavaScript)

const token = "XXX"; // use your access token here

async function createHighlights(highlights) {
  const response = await fetch("https://api.glasp.co/v1/highlights/create", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ highlights }),
  });
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }
  return await response.json();
}

// Example usage:
const highlights = [
  {
    title: "Example Domain",
    url: "https://example.com/",
    text: "This domain is for use in illustrative examples in documents.",
    author: "Example Author",
    color: "yellow",
    note: "My note about this highlight",
    highlighted_at: "2025-04-30T12:00:00Z",
    tags: ["Test", "Example"],
  },
];

const created = await createHighlights(highlights);

Highlight Update

Update existing highlights in your Glasp account. Each highlight must include url and highlight_id.

PATCHhttps://api.glasp.co/v1/highlights/update

Authentication

Bearer token in header. Get token from settings.

Authorization: BearerYOUR_ACCESS_TOKEN

Rate Limiting

30 requests/minute. Exceeding returns 429.

Query Parameters

Array of highlights to update. Each highlight must include at least highlight_id.

ParameterTypeRequiredDescription
urlstringYesURL of the source content. Used as a document identifier (max 2048 chars)
highlight_idstringYesHighlight ID to update
textstringNoThe highlight text (max 8192 chars)
colorenumNoHighlight color (one of: pink, yellow, blue, green)
notestringNoHighlight note (max 8192 chars)
locationnumberNoHighlight's location in the source content. For videos or podcasts, this refers to the start time in seconds. For books, it could be the page or line number.
highlight_urlstringNoUnique URL for the specific highlight (eg. a concrete tweet in a thread or a podcast snippet). Use this only if it differs from the main source URL.

Response

  • Status code: 200
  • Response object containing updated highlights.
Example Response
{
  id: "page123",
  title: "Example Domain",
  author: "Example Author",
  thumbnail_url: "https://example.com/thumbnail.jpg",
  url: "https://example.com/",
  glasp_url: "https://glasp.co/user/p/page123",
  domain: "example.com",
  category: "article",
  document_note: "",
  summary: "",
  tags: ["Test", "Example"],
  is_favorite: false,
  created_at: "2024-01-06T12:00:00Z",
  updated_at: "2024-01-06T12:00:00Z",
  highlights: [
    {
      id: "highlight123",
      text: "This domain is for use in illustrative examples in documents.",
      note: "My note about this highlight",
      color: "yellow",
      highlighted_at: "2024-01-06T12:00:00Z",
      created_at: "2024-01-06T12:00:00Z",
      updated_at: "2024-01-06T12:00:00Z",
      url: "https://example.com/",
      location: 123,
      location_type: "time_offset",
      highlight_url: "https://example.com/#highlightId",
    },
  ],
}
Response Interface
interface HighlightUpdateResponse {
  id: string;
  title: string;
  author: string;
  thumbnail_url: string;
  url: string;
  glasp_url: string;
  domain: string;
  category: "article" | "video" | "tweet" | "pdf" | "book";
  document_note: string | null;
  summary: string;
  tags: string[];
  is_favorite: boolean;
  created_at: string; // ISO date string
  updated_at: string; // ISO date string
  highlights: {
    id: string;
    text: string;
    note: string;
    color: "pink" | "yellow" | "blue" | "green";
    highlighted_at: string; // ISO date string
    created_at: string; // ISO date string
    updated_at: string; // ISO date string
    url: string;
    location: number | null; // YouTube timestamp in seconds
    location_type: "page" | "location" | "time_offset";
    highlight_url: string; // unique URL for the highlight
  }[];
}

Example Request (JavaScript)

const token = "XXX"; // use your access token here

async function updateHighlight(highlightData) {
  const response = await fetch("https://api.glasp.co/v1/highlights/update", {
    method: "PATCH",
    headers: {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ ...highlightData }),
  });
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }
  return await response.json();
}

// Example usage:
const highlightData = {
  url: "https://example.com/", // replace with the actual URL
  highlight_id: "highlightId", // replace with the actual highlight ID
  color: "yellow",
  note: "My note about this highlight",
  location: 123,
  highlight_url: "https://example.com/#highlightId", // unique URL for the highlight (if any)
};

const updated = await updateHighlight(highlightData);

Highlight Delete

Delete existing highlight or all highlights in a document. Each highlight must include url and highlight_id.

DELETEhttps://api.glasp.co/v1/highlights/delete

Authentication

Bearer token in header. Get token from settings.

Authorization: BearerYOUR_ACCESS_TOKEN

Rate Limiting

15 requests/minute. Exceeding returns 429.

Query Parameters

Please provide either highlight_id or delete_document.

ParameterTypeRequiredDescription
urlstringYesURL of the source content. Used as a document identifier (max 2048 chars)
highlight_idstringNoHighlight ID to delete
delete_documentbooleanNoDelete all highlights in the document. If true, highlight_id is ignored. Default: false

Response

  • Status code: 200

Example Request (JavaScript)

const token = "XXX"; // use your access token here

async function deleteHighlight(highlightData) {
  const response = await fetch("https://api.glasp.co/v1/highlights/delete", {
    method: "DELETE",
    headers: {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ ...highlightData }),
  });
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }
  return await response.json();
}

// Example usage:
const highlightData = {
  url: "https://example.com/", // replace with the actual URL
  highlight_id: "highlightId", // replace with the actual highlight ID
};

const deleted = await deleteHighlight(highlightData);

Kindle Highlight Export

Retrieve your Kindle highlights with optional filtering and pagination. Kindle highlights are read-only via the API — they are sourced from Amazon through the Glasp Kindle Extension / CSV import.

GEThttps://api.glasp.co/v1/kindle-highlights/export

Authentication

Bearer token in header. Get token from settings.

Authorization: BearerYOUR_ACCESS_TOKEN

Rate Limiting

100 requests/minute. Exceeding returns 429.

Query Parameters

Optional query parameters for pagination and filtering.

ParameterTypeRequiredDescription
pageCursorstringNoPagination cursor from previous response.
updatedAfterstringNoISO date string to get Kindle highlights updated after this date.

Response

  • Status code: 200
  • Response object containing Kindle highlights and pagination info.
Example Response
{
  "count": 1,
  "nextPageCursor": "2024-01-06T12:00:00Z",
  "results": [
    {
      "id": "book123",
      "title": "Sapiens: A Brief History of Humankind",
      "author": "Yuval Noah Harari",
      "thumbnail_url": "https://m.media-amazon.com/images/I/example.jpg",
      "url": "https://www.amazon.com/dp/0062316095",
      "glasp_url": "https://glasp.co/user/kindle/book123",
      "domain": "amazon.com",
      "category": "book",
      "document_note": "",
      "summary": "",
      "tags": ["history", "anthropology"],
      "is_favorite": false,
      "created_at": "2024-01-06T12:00:00Z",
      "updated_at": "2024-01-06T12:00:00Z",
      "highlights": [
        {
          "id": "highlight123",
          "text": "We did not domesticate wheat. It domesticated us.",
          "note": "A great reframing of agricultural revolution.",
          "color": "yellow",
          "highlighted_at": "2024-01-06T12:00:00Z",
          "created_at": "2024-01-06T12:00:00Z",
          "updated_at": "2024-01-06T12:00:00Z",
          "url": "https://www.amazon.com/dp/0062316095",
          "location": 1247,
          "location_type": "location",
          "highlight_url": ""
        }
      ]
    }
  ]
}
Response Interface
interface KindleHighlightExportResponse {
  count: number;
  nextPageCursor: string | null;
  results: {
    id: string;
    title: string;
    author: string;
    thumbnail_url: string;
    url: string; // Amazon product URL
    glasp_url: string; // https://glasp.co/{uid}/kindle/{id}
    domain: string;
    category: "book"; // Always "book" for Kindle
    document_note: string | null;
    summary: string;
    tags: string[];
    is_favorite: boolean;
    created_at: string; // ISO date string
    updated_at: string; // ISO date string
    highlights: {
      id: string;
      text: string;
      note: string;
      color: "pink" | "yellow" | "blue" | "orange"
      highlighted_at: string; // ISO date string
      created_at: string; // ISO date string
      updated_at: string; // ISO date string
      url: string;
      location: number | null; // Kindle location number
      location_type: "page" | "location" | "time_offset";
      highlight_url: string;
    }[];
  }[];
}

Example Request (JavaScript)

const token = "XXX"; // use your access token here

async function getAllKindleHighlights(updatedAfter = null) {
  let allHighlights = [];
  let nextPageCursor = null;

  do {
    const queryParams = new URLSearchParams();
    if (nextPageCursor) {
      queryParams.append("pageCursor", nextPageCursor);
    }
    if (updatedAfter) {
      queryParams.append("updatedAfter", updatedAfter);
    }
    try {
      const response = await fetch(
        `https://api.glasp.co/v1/kindle-highlights/export?${queryParams.toString()}`,
        {
          headers: {
            Authorization: `Bearer ${token}`,
          },
        }
      );
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const data = await response.json();
      if (data.results && data.results.length > 0) {
        const highlights = data.results.map((result) => result);
        allHighlights = allHighlights.concat(highlights);
      }
      nextPageCursor = data?.nextPageCursor || null;
      if (!nextPageCursor) {
        break;
      }
    } catch (error) {
      console.error("Error fetching Kindle highlights:", error);
      break;
    }
  } while (nextPageCursor);
  return allHighlights;
}

// Get all of a user's Kindle highlights from all time
const allKindleHighlights = await getAllKindleHighlights();

// If you want to get new Kindle highlights updated since your last fetch, do this:
const lastFetchedAt = new Date(Date.now() - 24 * 60 * 60 * 1000);
const newKindleHighlights = await getAllKindleHighlights(lastFetchedAt.toISOString());

More Coming...

We’re constantly improving our API and adding new features. Stay tuned for updates, or reach out if you have feedback!