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.
- Base URL: https://api.glasp.co
- Authentication: Use your Glasp Access Token in the Authorization header.
- Rate Limits: Each endpoint has its own rate limit — refer to each section below for details.
- Available Endpoints:
Highlight Export
Retrieve your Glasp highlights with optional filtering and pagination.
GEThttps://api.glasp.co/v1/highlights/exportAuthentication
Bearer token in header. Get token from settings.
YOUR_ACCESS_TOKENRate Limiting
100 requests/minute. Exceeding returns 429.
Query Parameters
Optional query parameters for pagination and filtering.
| Parameter | Type | Required | Description |
|---|---|---|---|
| pageCursor | string | No | Pagination cursor from previous response. |
| updatedAfter | string | No | ISO 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/createAuthentication
Bearer token in header. Get token from settings.
YOUR_ACCESS_TOKENRate 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
| title | string | Yes | Title of the source (max 512 chars) |
| url | string | Yes | URL of the source (max 2048 chars) |
| text | string | Yes | The highlight text (max 8192 chars) |
| author | string | No | Author of the source (max 512 chars) |
| thumbnail_url | string | No | Thumbnail image URL (max 2048 chars) |
| color | enum | No | Highlight color (one of: pink, yellow, blue, green; default: pink) |
| note | string | No | Highlight note (max 8192 chars) |
| tags | string[] | No | Tags for the highlight (array of up to 5 strings, each max 25 chars) |
| location | number | No | Highlight'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_type | enum | No | One of: page, location, time_offset (default: time_offset). This is mainly for videos, podcasts, and books. |
| highlighted_at | string | No | When the highlight was made (ISO date string) |
| highlight_url | string | No | Unique 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/updateAuthentication
Bearer token in header. Get token from settings.
YOUR_ACCESS_TOKENRate Limiting
30 requests/minute. Exceeding returns 429.
Query Parameters
Array of highlights to update. Each highlight must include at least highlight_id.
| Parameter | Type | Required | Description |
|---|---|---|---|
| url | string | Yes | URL of the source content. Used as a document identifier (max 2048 chars) |
| highlight_id | string | Yes | Highlight ID to update |
| text | string | No | The highlight text (max 8192 chars) |
| color | enum | No | Highlight color (one of: pink, yellow, blue, green) |
| note | string | No | Highlight note (max 8192 chars) |
| location | number | No | Highlight'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_url | string | No | Unique 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/deleteAuthentication
Bearer token in header. Get token from settings.
YOUR_ACCESS_TOKENRate Limiting
15 requests/minute. Exceeding returns 429.
Query Parameters
Please provide either highlight_id or delete_document.
| Parameter | Type | Required | Description |
|---|---|---|---|
| url | string | Yes | URL of the source content. Used as a document identifier (max 2048 chars) |
| highlight_id | string | No | Highlight ID to delete |
| delete_document | boolean | No | Delete 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/exportAuthentication
Bearer token in header. Get token from settings.
YOUR_ACCESS_TOKENRate Limiting
100 requests/minute. Exceeding returns 429.
Query Parameters
Optional query parameters for pagination and filtering.
| Parameter | Type | Required | Description |
|---|---|---|---|
| pageCursor | string | No | Pagination cursor from previous response. |
| updatedAfter | string | No | ISO 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!