ultra-igdl 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +476 -371
- package/dist/cli/index.cjs +1 -1
- package/dist/cli/index.cjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,269 +1,229 @@
|
|
|
1
1
|
# ultra-igdl
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**Beginner-friendly Instagram media extractor for Node.js**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Get direct download links (images and videos) from Instagram posts, reels, carousels, stories, and highlights. Use it from the **command line** or inside your **JavaScript / TypeScript** app.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
## Table of contents
|
|
7
|
+
[](https://www.npmjs.com/package/ultra-igdl)
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
2. [Requirements](#requirements)
|
|
13
|
-
3. [Installation](#installation)
|
|
14
|
-
4. [Quick start (beginner)](#quick-start-beginner)
|
|
15
|
-
5. [Instagram session (important)](#instagram-session-important)
|
|
16
|
-
6. [CLI guide](#cli-guide)
|
|
17
|
-
7. [Supported URLs](#supported-urls)
|
|
18
|
-
8. [Response format](#response-format)
|
|
19
|
-
9. [Content types explained](#content-types-explained)
|
|
20
|
-
10. [JavaScript / TypeScript API](#javascript--typescript-api)
|
|
21
|
-
11. [Configuration options](#configuration-options)
|
|
22
|
-
12. [Pro features](#pro-features)
|
|
23
|
-
13. [Error codes & troubleshooting](#error-codes--troubleshooting)
|
|
24
|
-
14. [Examples in this repo](#examples-in-this-repo)
|
|
25
|
-
15. [Architecture](#architecture)
|
|
26
|
-
16. [Development](#development)
|
|
27
|
-
17. [Publishing to npm](#publishing-to-npm)
|
|
28
|
-
18. [Legal & disclaimer](#legal--disclaimer)
|
|
29
|
-
19. [License](#license)
|
|
9
|
+
**Links:** [npm package](https://www.npmjs.com/package/ultra-igdl) · [GitHub](https://github.com/WH173-5P1D3R/ultra-igdl) · [Report issues](https://github.com/WH173-5P1D3R/ultra-igdl/issues)
|
|
30
10
|
|
|
31
11
|
---
|
|
32
12
|
|
|
33
|
-
##
|
|
13
|
+
## Table of contents
|
|
34
14
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
15
|
+
1. [What does this do?](#1-what-does-this-do)
|
|
16
|
+
2. [Who is this for?](#2-who-is-this-for)
|
|
17
|
+
3. [Before you start (requirements)](#3-before-you-start-requirements)
|
|
18
|
+
4. [Install Node.js and the package](#4-install-nodejs-and-the-package)
|
|
19
|
+
5. [Your first download (CLI)](#5-your-first-download-cli)
|
|
20
|
+
6. [Your first download (code)](#6-your-first-download-code)
|
|
21
|
+
7. [Understanding the JSON response](#7-understanding-the-json-response)
|
|
22
|
+
8. [Instagram session — why and how](#8-instagram-session--why-and-how)
|
|
23
|
+
9. [Content types (posts, reels, carousels, stories)](#9-content-types-posts-reels-carousels-stories)
|
|
24
|
+
10. [Command line (CLI) — full guide](#10-command-line-cli--full-guide)
|
|
25
|
+
11. [JavaScript / TypeScript API](#11-javascript--typescript-api)
|
|
26
|
+
12. [Configuration options](#12-configuration-options)
|
|
27
|
+
13. [Batch URLs and bots](#13-batch-urls-and-bots)
|
|
28
|
+
14. [Error codes and fixes](#14-error-codes-and-fixes)
|
|
29
|
+
15. [FAQ and troubleshooting](#15-faq-and-troubleshooting)
|
|
30
|
+
16. [Examples in this repository](#16-examples-in-this-repository)
|
|
31
|
+
17. [Legal and privacy](#17-legal-and-privacy)
|
|
32
|
+
18. [License](#18-license)
|
|
40
33
|
|
|
41
34
|
---
|
|
42
35
|
|
|
43
|
-
##
|
|
36
|
+
## 1. What does this do?
|
|
44
37
|
|
|
45
|
-
|
|
46
|
-
- **npm** 9+ (or pnpm/yarn)
|
|
47
|
-
- Public Instagram URLs (no login required for basic post/reel preview)
|
|
48
|
-
- **Optional:** Instagram `sessionid` cookie for carousels (all slides), reel MP4, stories, highlights
|
|
38
|
+
You give **ultra-igdl** an Instagram link. It returns:
|
|
49
39
|
|
|
50
|
-
|
|
40
|
+
- **Direct media URLs** (CDN links you can open or save)
|
|
41
|
+
- **Caption** and **username**
|
|
42
|
+
- Optional **likes / comments** counts when Instagram shows them
|
|
43
|
+
- Hints in `tags` (for example: carousel detected, session recommended)
|
|
51
44
|
|
|
52
|
-
|
|
45
|
+
It works **without logging in** for many public posts and reels, but Instagram limits logged-out access. For **full carousels**, **reel video files**, **stories**, and **highlights**, you usually need a **browser session cookie** (explained in [section 8](#8-instagram-session--why-and-how)).
|
|
53
46
|
|
|
54
|
-
|
|
47
|
+
---
|
|
55
48
|
|
|
56
|
-
|
|
57
|
-
npm install ultra-igdl
|
|
58
|
-
```
|
|
49
|
+
## 2. Who is this for?
|
|
59
50
|
|
|
60
|
-
|
|
51
|
+
| You are… | Start here |
|
|
52
|
+
|----------|------------|
|
|
53
|
+
| **Complete beginner** | [Section 4](#4-install-nodejs-and-the-package) → [Section 5](#5-your-first-download-cli) (CLI with `npx`) |
|
|
54
|
+
| **JavaScript developer** | [Section 6](#6-your-first-download-code) → [Section 11](#11-javascript--typescript-api) |
|
|
55
|
+
| **Bot builder** (Telegram, Discord, etc.) | [Section 8](#8-instagram-session--why-and-how) + [Section 13](#13-batch-urls-and-bots) |
|
|
56
|
+
| **TypeScript user** | [Section 11](#11-javascript--typescript-api) (types included) |
|
|
61
57
|
|
|
62
|
-
|
|
58
|
+
No Instagram API key is required. You only need Node.js and a valid Instagram URL.
|
|
63
59
|
|
|
64
|
-
|
|
60
|
+
---
|
|
65
61
|
|
|
66
|
-
|
|
67
|
-
2. Add `.npmrc` (see [`.npmrc.github.example`](./.npmrc.github.example)):
|
|
62
|
+
## 3. Before you start (requirements)
|
|
68
63
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
64
|
+
| Requirement | Details |
|
|
65
|
+
|-------------|---------|
|
|
66
|
+
| **Node.js** | Version **20.18.1 or newer** (22 LTS is fine). Check with `node -v` |
|
|
67
|
+
| **npm** | Comes with Node. Check with `npm -v` |
|
|
68
|
+
| **Instagram URL** | A normal link you can open in a browser (post, reel, story, etc.) |
|
|
69
|
+
| **Session cookie** | Optional but strongly recommended for carousels, reel MP4, stories |
|
|
73
70
|
|
|
74
|
-
|
|
71
|
+
**Check Node version:**
|
|
75
72
|
|
|
76
73
|
```bash
|
|
77
|
-
|
|
74
|
+
node -v
|
|
75
|
+
# Should print v20.18.1 or higher (e.g. v22.x.x)
|
|
78
76
|
```
|
|
79
77
|
|
|
80
|
-
|
|
81
|
-
import { ultraigdl } from "@wh173-5p1d3r/ultra-igdl";
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
Package page: https://github.com/WH173-5P1D3R/ultra-igdl/packages
|
|
85
|
-
|
|
86
|
-
CLI only (no install into project):
|
|
87
|
-
|
|
88
|
-
```bash
|
|
89
|
-
npx ultra-igdl --help
|
|
90
|
-
```
|
|
78
|
+
If Node is too old, install the latest LTS from [https://nodejs.org](https://nodejs.org).
|
|
91
79
|
|
|
92
80
|
---
|
|
93
81
|
|
|
94
|
-
##
|
|
82
|
+
## 4. Install Node.js and the package
|
|
95
83
|
|
|
96
|
-
###
|
|
97
|
-
|
|
98
|
-
```js
|
|
99
|
-
import { ultraigdl } from "ultra-igdl";
|
|
100
|
-
|
|
101
|
-
const ig = new ultraigdl();
|
|
102
|
-
const result = await ig.download("https://www.instagram.com/reel/SHORTCODE/");
|
|
84
|
+
### Option A — Use without installing (fastest try)
|
|
103
85
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
console.log("Caption:", result.caption);
|
|
107
|
-
console.log("Files:", result.media.length);
|
|
108
|
-
result.media.forEach((m, i) => console.log(i + 1, m.type, m.url));
|
|
109
|
-
} else {
|
|
110
|
-
console.error(result.code, result.message);
|
|
111
|
-
}
|
|
86
|
+
```bash
|
|
87
|
+
npx ultra-igdl --help
|
|
112
88
|
```
|
|
113
89
|
|
|
114
|
-
|
|
90
|
+
`npx` downloads the tool temporarily and runs it. Good for a quick test.
|
|
115
91
|
|
|
116
|
-
|
|
117
|
-
const { ultraigdl } = require("ultra-igdl");
|
|
118
|
-
|
|
119
|
-
(async () => {
|
|
120
|
-
const ig = new ultraigdl();
|
|
121
|
-
const result = await ig.download("https://www.instagram.com/p/SHORTCODE/");
|
|
122
|
-
console.log(result);
|
|
123
|
-
})();
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
### 3. CLI (JSON)
|
|
92
|
+
### Option B — Add to your project (recommended for apps)
|
|
127
93
|
|
|
128
94
|
```bash
|
|
129
|
-
|
|
95
|
+
mkdir my-ig-downloader
|
|
96
|
+
cd my-ig-downloader
|
|
97
|
+
npm init -y
|
|
98
|
+
npm install ultra-igdl
|
|
130
99
|
```
|
|
131
100
|
|
|
132
|
-
|
|
101
|
+
You can then `import` or `require` it in your code (see [section 6](#6-your-first-download-code)).
|
|
133
102
|
|
|
134
103
|
---
|
|
135
104
|
|
|
136
|
-
##
|
|
105
|
+
## 5. Your first download (CLI)
|
|
137
106
|
|
|
138
|
-
|
|
107
|
+
### Step 1 — Copy an Instagram URL
|
|
139
108
|
|
|
140
|
-
|
|
141
|
-
|---------|-----------------|----------------------------------------|
|
|
142
|
-
| Single post image | Usually yes | Yes (full resolution) |
|
|
143
|
-
| **Carousel (2+ photos)** | Often **1 slide only** | **All slides** |
|
|
144
|
-
| **Reel MP4** | Often thumbnail only | **Video URL** |
|
|
145
|
-
| **Story** | Usually fails / preview | **Media URL** |
|
|
146
|
-
| **Highlight** | Limited | **Video** when available |
|
|
109
|
+
Example (replace with a real public post):
|
|
147
110
|
|
|
148
|
-
|
|
111
|
+
```text
|
|
112
|
+
https://www.instagram.com/p/SHORTCODE/
|
|
113
|
+
```
|
|
149
114
|
|
|
150
|
-
|
|
151
|
-
2. Open DevTools → **Application** → **Cookies** → `https://www.instagram.com`.
|
|
152
|
-
3. Copy:
|
|
153
|
-
- `sessionid`
|
|
154
|
-
- `csrftoken`
|
|
155
|
-
- `ds_user_id`
|
|
115
|
+
### Step 2 — Run the CLI
|
|
156
116
|
|
|
157
|
-
|
|
117
|
+
**Linux / macOS / Git Bash:**
|
|
158
118
|
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
cookies:
|
|
162
|
-
"sessionid=YOUR_ID; csrftoken=YOUR_CSRF; ds_user_id=YOUR_USER_ID",
|
|
163
|
-
});
|
|
119
|
+
```bash
|
|
120
|
+
npx ultra-igdl "https://www.instagram.com/p/SHORTCODE/"
|
|
164
121
|
```
|
|
165
122
|
|
|
166
|
-
|
|
123
|
+
**Windows PowerShell** — always put the URL in **double quotes**:
|
|
167
124
|
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
sessionId: "YOUR_SESSIONID_VALUE",
|
|
171
|
-
});
|
|
125
|
+
```powershell
|
|
126
|
+
npx ultra-igdl "https://www.instagram.com/p/SHORTCODE/"
|
|
172
127
|
```
|
|
173
128
|
|
|
174
|
-
###
|
|
129
|
+
### Step 3 — Read the output
|
|
175
130
|
|
|
176
|
-
|
|
131
|
+
Without `--json`, you get a short summary: username, caption preview, and a list of media items with type and URL.
|
|
132
|
+
|
|
133
|
+
For **machine-readable output** (scripts, bots):
|
|
177
134
|
|
|
178
135
|
```bash
|
|
179
|
-
# Linux / macOS
|
|
180
|
-
export INSTAGRAM_COOKIES="sessionid=...; csrftoken=...; ds_user_id=..."
|
|
181
136
|
npx ultra-igdl "https://www.instagram.com/p/SHORTCODE/" --json
|
|
182
137
|
```
|
|
183
138
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
npx ultra-igdl "https://www.instagram.com/p/SHORTCODE/" --
|
|
139
|
+
### Step 4 — Save files to disk
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
npx ultra-igdl "https://www.instagram.com/p/SHORTCODE/" --download --output ./downloads
|
|
188
143
|
```
|
|
189
144
|
|
|
190
|
-
|
|
145
|
+
Files go under `./downloads/<username>/`.
|
|
191
146
|
|
|
192
147
|
---
|
|
193
148
|
|
|
194
|
-
##
|
|
149
|
+
## 6. Your first download (code)
|
|
195
150
|
|
|
196
|
-
|
|
197
|
-
npx ultra-igdl <url> [options]
|
|
198
|
-
npx ultra-igdl urls.txt # one URL per line
|
|
199
|
-
```
|
|
151
|
+
Create a file `test.mjs` in your project folder (after `npm install ultra-igdl`).
|
|
200
152
|
|
|
201
|
-
|
|
202
|
-
|------|-------|-------------|
|
|
203
|
-
| `--json` | `-j` | Print full API response as JSON |
|
|
204
|
-
| `--download` | `-d` | Save media files under `--output` |
|
|
205
|
-
| `--output <dir>` | `-o` | Download folder (default: `./downloads`) |
|
|
206
|
-
| `--verbose` | `-v` | Debug logging |
|
|
207
|
-
| `--help` | `-h` | Show help |
|
|
153
|
+
### ESM (modern Node — `"type": "module"` in package.json, or `.mjs` file)
|
|
208
154
|
|
|
209
|
-
|
|
155
|
+
```js
|
|
156
|
+
import { ultraigdl } from "ultra-igdl";
|
|
210
157
|
|
|
211
|
-
|
|
212
|
-
|
|
158
|
+
const ig = new ultraigdl();
|
|
159
|
+
const url = "https://www.instagram.com/reel/SHORTCODE/";
|
|
213
160
|
|
|
214
|
-
|
|
215
|
-
|
|
161
|
+
const result = await ig.download(url);
|
|
162
|
+
|
|
163
|
+
if (result.code === 200) {
|
|
164
|
+
console.log("Creator:", result.username);
|
|
165
|
+
console.log("Caption:", result.caption);
|
|
166
|
+
console.log("Number of files:", result.media.length);
|
|
167
|
+
for (const item of result.media) {
|
|
168
|
+
console.log(item.type, item.url);
|
|
169
|
+
}
|
|
170
|
+
} else {
|
|
171
|
+
console.log("Failed:", result.code, result.message);
|
|
172
|
+
}
|
|
216
173
|
```
|
|
217
174
|
|
|
218
|
-
|
|
175
|
+
Run:
|
|
219
176
|
|
|
220
177
|
```bash
|
|
221
|
-
|
|
222
|
-
|
|
178
|
+
node test.mjs
|
|
179
|
+
```
|
|
223
180
|
|
|
224
|
-
|
|
225
|
-
npx ultra-igdl "https://www.instagram.com/p/ABC123/" --json
|
|
181
|
+
### CommonJS (`.cjs` file or no `"type": "module"`)
|
|
226
182
|
|
|
227
|
-
|
|
228
|
-
|
|
183
|
+
```js
|
|
184
|
+
const { ultraigdl } = require("ultra-igdl");
|
|
229
185
|
|
|
230
|
-
|
|
231
|
-
|
|
186
|
+
(async () => {
|
|
187
|
+
const ig = new ultraigdl();
|
|
188
|
+
const result = await ig.download("https://www.instagram.com/p/SHORTCODE/");
|
|
189
|
+
console.log(JSON.stringify(result, null, 2));
|
|
190
|
+
})();
|
|
232
191
|
```
|
|
233
192
|
|
|
234
|
-
|
|
193
|
+
### Handle success vs error (important pattern)
|
|
235
194
|
|
|
236
|
-
|
|
195
|
+
Every call returns an object with a **`code`** field:
|
|
237
196
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
| Post | `https://www.instagram.com/p/{shortcode}/` |
|
|
241
|
-
| Reel | `https://www.instagram.com/reel/{shortcode}/` |
|
|
242
|
-
| IGTV | `https://www.instagram.com/tv/{shortcode}/` |
|
|
243
|
-
| Story | `https://www.instagram.com/stories/{username}/{storyId}/` |
|
|
244
|
-
| Highlight (path) | `https://www.instagram.com/stories/highlights/{id}/` |
|
|
245
|
-
| Highlight (share) | `https://www.instagram.com/s/{token}?story_media_id=...` |
|
|
246
|
-
|
|
247
|
-
Validate before download:
|
|
197
|
+
- **`200`** — success; use `media`, `caption`, `username`
|
|
198
|
+
- **Anything else** — error; read `message`
|
|
248
199
|
|
|
249
200
|
```js
|
|
250
|
-
const
|
|
201
|
+
const result = await ig.download(url);
|
|
202
|
+
if (result.code !== 200) {
|
|
203
|
+
throw new Error(`${result.code}: ${result.message}`);
|
|
204
|
+
}
|
|
205
|
+
// TypeScript: narrow with if (result.code === 200) { ... result.media }
|
|
251
206
|
```
|
|
252
207
|
|
|
253
208
|
---
|
|
254
209
|
|
|
255
|
-
##
|
|
210
|
+
## 7. Understanding the JSON response
|
|
256
211
|
|
|
257
|
-
###
|
|
212
|
+
### Successful response (`code: 200`)
|
|
258
213
|
|
|
259
214
|
```json
|
|
260
215
|
{
|
|
261
216
|
"code": 200,
|
|
262
|
-
"meta": {
|
|
217
|
+
"meta": {
|
|
218
|
+
"extractor": "ultra-igdl",
|
|
219
|
+
"version": "1.0.2"
|
|
220
|
+
},
|
|
221
|
+
"username": "creator",
|
|
222
|
+
"caption": "Post caption as one clean line",
|
|
263
223
|
"media": [
|
|
264
224
|
{
|
|
265
225
|
"type": "image",
|
|
266
|
-
"url": "https://...cdninstagram
|
|
226
|
+
"url": "https://...cdninstagram.com/....jpg",
|
|
267
227
|
"width": 1440,
|
|
268
228
|
"height": 1800
|
|
269
229
|
},
|
|
@@ -276,8 +236,6 @@ const { valid, type, normalized } = await ig.validate(url);
|
|
|
276
236
|
"duration": 24
|
|
277
237
|
}
|
|
278
238
|
],
|
|
279
|
-
"caption": "Post caption as a single clean line for posts",
|
|
280
|
-
"username": "creator",
|
|
281
239
|
"engagement": {
|
|
282
240
|
"likes": 1200,
|
|
283
241
|
"comments": 45
|
|
@@ -286,190 +244,392 @@ const { valid, type, normalized } = await ig.validate(url);
|
|
|
286
244
|
}
|
|
287
245
|
```
|
|
288
246
|
|
|
289
|
-
### Media object
|
|
247
|
+
### Media object fields
|
|
290
248
|
|
|
291
|
-
| Field |
|
|
292
|
-
|
|
293
|
-
| `type` | `"image"`
|
|
294
|
-
| `url` |
|
|
295
|
-
| `thumbnail` |
|
|
296
|
-
| `width` / `height` |
|
|
297
|
-
| `duration` |
|
|
249
|
+
| Field | Meaning |
|
|
250
|
+
|-------|---------|
|
|
251
|
+
| `type` | `"image"` or `"video"` |
|
|
252
|
+
| `url` | Direct link to the file (use as-is; do not remove `?` parameters) |
|
|
253
|
+
| `thumbnail` | Preview image for videos |
|
|
254
|
+
| `width` / `height` | Pixel size when known |
|
|
255
|
+
| `duration` | Video length in seconds |
|
|
298
256
|
|
|
299
|
-
### Tags (`tags` array)
|
|
257
|
+
### Tags (`tags` array) — what they mean for you
|
|
300
258
|
|
|
301
|
-
| Tag | Meaning |
|
|
302
|
-
|
|
303
|
-
| `carousel` | Multi-
|
|
304
|
-
| `partial_carousel` | Carousel detected but only one
|
|
305
|
-
| `session_recommended` | Add `
|
|
306
|
-
| `likes_hidden` | Creator hid like counts |
|
|
307
|
-
| `comments_hidden` | Comments
|
|
308
|
-
| `engagement_hidden` | Both
|
|
259
|
+
| Tag | Meaning | What you should do |
|
|
260
|
+
|-----|---------|-------------------|
|
|
261
|
+
| `carousel` | Multi-photo post; all slides returned | Nothing — you got the full carousel |
|
|
262
|
+
| `partial_carousel` | Carousel detected but only one image returned | Add session cookies ([section 8](#8-instagram-session--why-and-how)) |
|
|
263
|
+
| `session_recommended` | Logged-in session would improve results | Add `cookies` or `sessionId` |
|
|
264
|
+
| `likes_hidden` | Creator hid like counts | Normal — not an error |
|
|
265
|
+
| `comments_hidden` | Comments hidden or disabled | Normal — not an error |
|
|
266
|
+
| `engagement_hidden` | Both hidden | Normal — not an error |
|
|
309
267
|
|
|
310
|
-
### Error (`code`
|
|
268
|
+
### Error response (`code` not 200)
|
|
311
269
|
|
|
312
270
|
```json
|
|
313
271
|
{
|
|
314
272
|
"code": 404,
|
|
315
273
|
"message": "Media not found",
|
|
316
|
-
"meta": { "extractor": "ultra-igdl", "version": "1.0.
|
|
274
|
+
"meta": { "extractor": "ultra-igdl", "version": "1.0.1" }
|
|
317
275
|
}
|
|
318
276
|
```
|
|
319
277
|
|
|
320
|
-
Some responses include `retryAfterMs` when using
|
|
278
|
+
Some responses include `retryAfterMs` when using fast-response mode ([section 13](#13-batch-urls-and-bots)).
|
|
321
279
|
|
|
322
280
|
---
|
|
323
281
|
|
|
324
|
-
##
|
|
282
|
+
## 8. Instagram session — why and how
|
|
283
|
+
|
|
284
|
+
Instagram shows **less content** to visitors who are not logged in.
|
|
325
285
|
|
|
326
|
-
|
|
286
|
+
| Feature | Without session | With session (`cookies` / `sessionId`) |
|
|
287
|
+
|---------|-----------------|--------------------------------------|
|
|
288
|
+
| Single post image | Usually works | Works (often higher resolution) |
|
|
289
|
+
| **Carousel (2+ photos)** | Often **only 1 slide** | **All slides** |
|
|
290
|
+
| **Reel MP4 video** | Often thumbnail only | **Full video URL** |
|
|
291
|
+
| **Story** | Usually fails or preview only | **Works** (if story is still live) |
|
|
292
|
+
| **Highlight** | Limited | More reliable |
|
|
293
|
+
|
|
294
|
+
### How to get cookies (Chrome / Edge / Firefox)
|
|
295
|
+
|
|
296
|
+
1. Open [https://www.instagram.com](https://www.instagram.com) and **log in**.
|
|
297
|
+
2. Press **F12** to open Developer Tools.
|
|
298
|
+
3. Go to **Application** (Chrome) or **Storage** (Firefox) → **Cookies** → `https://www.instagram.com`.
|
|
299
|
+
4. Copy these values:
|
|
300
|
+
- `sessionid`
|
|
301
|
+
- `csrftoken`
|
|
302
|
+
- `ds_user_id`
|
|
303
|
+
|
|
304
|
+
**Treat these like a password.** Never post them on GitHub, Discord, or screenshots.
|
|
305
|
+
|
|
306
|
+
### Use in code — full cookie string (recommended)
|
|
307
|
+
|
|
308
|
+
```js
|
|
309
|
+
const ig = new ultraigdl({
|
|
310
|
+
cookies:
|
|
311
|
+
"sessionid=YOUR_SESSIONID; csrftoken=YOUR_CSRF; ds_user_id=YOUR_USER_ID",
|
|
312
|
+
});
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### Use in code — session id only
|
|
316
|
+
|
|
317
|
+
```js
|
|
318
|
+
const ig = new ultraigdl({
|
|
319
|
+
sessionId: "YOUR_SESSIONID_VALUE",
|
|
320
|
+
});
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Use with environment variables (CLI and scripts)
|
|
324
|
+
|
|
325
|
+
Create a `.env` file in your project folder (add `.env` to `.gitignore`):
|
|
326
|
+
|
|
327
|
+
```env
|
|
328
|
+
INSTAGRAM_COOKIES=sessionid=xxx; csrftoken=xxx; ds_user_id=xxx
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Or only:
|
|
332
|
+
|
|
333
|
+
```env
|
|
334
|
+
INSTAGRAM_SESSION_ID=your_sessionid_value
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
The CLI loads `.env` from the current directory automatically.
|
|
338
|
+
|
|
339
|
+
**Linux / macOS terminal:**
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
export INSTAGRAM_COOKIES="sessionid=...; csrftoken=...; ds_user_id=..."
|
|
343
|
+
npx ultra-igdl "https://www.instagram.com/p/SHORTCODE/" --json
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
**Windows PowerShell** — use **two lines** (or semicolon before `npx`):
|
|
347
|
+
|
|
348
|
+
```powershell
|
|
349
|
+
$env:INSTAGRAM_COOKIES = "sessionid=...; csrftoken=...; ds_user_id=..."
|
|
350
|
+
npx ultra-igdl "https://www.instagram.com/p/SHORTCODE/" --json
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
One-line PowerShell alternative:
|
|
354
|
+
|
|
355
|
+
```powershell
|
|
356
|
+
$env:INSTAGRAM_COOKIES = "sessionid=...; csrftoken=...; ds_user_id=..."; npx ultra-igdl "https://www.instagram.com/p/SHORTCODE/" --json
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Load cookies from `process.env` in Node
|
|
360
|
+
|
|
361
|
+
```js
|
|
362
|
+
const ig = new ultraigdl({
|
|
363
|
+
cookies: process.env.INSTAGRAM_COOKIES,
|
|
364
|
+
});
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## 9. Content types (posts, reels, carousels, stories)
|
|
370
|
+
|
|
371
|
+
### Supported URL patterns
|
|
372
|
+
|
|
373
|
+
| Type | URL pattern |
|
|
374
|
+
|------|-------------|
|
|
375
|
+
| Post | `https://www.instagram.com/p/{shortcode}/` |
|
|
376
|
+
| Reel | `https://www.instagram.com/reel/{shortcode}/` |
|
|
377
|
+
| IGTV | `https://www.instagram.com/tv/{shortcode}/` |
|
|
378
|
+
| Story | `https://www.instagram.com/stories/{username}/{storyId}/` |
|
|
379
|
+
| Highlight | `https://www.instagram.com/stories/highlights/{id}/` |
|
|
380
|
+
| Highlight share link | `https://www.instagram.com/s/{token}?story_media_id=...` |
|
|
381
|
+
|
|
382
|
+
### Single-image post
|
|
327
383
|
|
|
328
384
|
```js
|
|
329
385
|
const result = await ig.download("https://www.instagram.com/p/SHORTCODE/");
|
|
330
|
-
// result.media.length
|
|
386
|
+
// result.media.length is often 1
|
|
331
387
|
```
|
|
332
388
|
|
|
333
|
-
###
|
|
389
|
+
### Carousel (multiple photos)
|
|
334
390
|
|
|
335
|
-
|
|
336
|
-
- Without session: often 1 image + tags `partial_carousel`, `session_recommended`.
|
|
337
|
-
- With session: all slides, tag `carousel`.
|
|
391
|
+
Same URL as a normal post (`/p/...`). No special mode — the library detects carousels automatically.
|
|
338
392
|
|
|
339
393
|
```js
|
|
340
394
|
const ig = new ultraigdl({ cookies: process.env.INSTAGRAM_COOKIES });
|
|
341
395
|
const result = await ig.download("https://www.instagram.com/p/SHORTCODE/");
|
|
342
|
-
console.log(result.media.length);
|
|
343
|
-
console.log(result.tags);
|
|
396
|
+
console.log("Slides:", result.media.length);
|
|
397
|
+
console.log("Tags:", result.tags);
|
|
344
398
|
```
|
|
345
399
|
|
|
346
|
-
|
|
400
|
+
If you see `partial_carousel` or `session_recommended`, add cookies from [section 8](#8-instagram-session--why-and-how).
|
|
401
|
+
|
|
402
|
+
### Reel (video)
|
|
347
403
|
|
|
348
404
|
```js
|
|
349
405
|
const ig = new ultraigdl({ sessionId: process.env.INSTAGRAM_SESSION_ID });
|
|
350
406
|
const result = await ig.download("https://www.instagram.com/reel/SHORTCODE/");
|
|
351
407
|
const video = result.media.find((m) => m.type === "video");
|
|
408
|
+
if (video) console.log("MP4:", video.url);
|
|
352
409
|
```
|
|
353
410
|
|
|
354
|
-
###
|
|
411
|
+
### Story
|
|
355
412
|
|
|
356
|
-
Requires session.
|
|
413
|
+
Requires session. The story must still be **live** (not expired after 24 hours).
|
|
357
414
|
|
|
358
415
|
```js
|
|
416
|
+
const ig = new ultraigdl({ cookies: process.env.INSTAGRAM_COOKIES });
|
|
359
417
|
const result = await ig.download(
|
|
360
|
-
"https://www.instagram.com/stories/username/
|
|
418
|
+
"https://www.instagram.com/stories/username/1234567890123456789/"
|
|
361
419
|
);
|
|
362
420
|
```
|
|
363
421
|
|
|
364
|
-
###
|
|
422
|
+
### Check a URL before downloading
|
|
423
|
+
|
|
424
|
+
```js
|
|
425
|
+
const check = await ig.validate("https://www.instagram.com/p/SHORTCODE/");
|
|
426
|
+
console.log(check.valid, check.type, check.normalized);
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
Or use the exported helper:
|
|
365
430
|
|
|
366
|
-
|
|
431
|
+
```js
|
|
432
|
+
import { validateUrl, parseInstagramUrl, isInstagramUrl } from "ultra-igdl";
|
|
433
|
+
|
|
434
|
+
console.log(isInstagramUrl(url));
|
|
435
|
+
console.log(parseInstagramUrl(url));
|
|
436
|
+
console.log(validateUrl(url));
|
|
437
|
+
```
|
|
367
438
|
|
|
368
439
|
---
|
|
369
440
|
|
|
370
|
-
##
|
|
441
|
+
## 10. Command line (CLI) — full guide
|
|
442
|
+
|
|
443
|
+
### Basic usage
|
|
444
|
+
|
|
445
|
+
```bash
|
|
446
|
+
npx ultra-igdl "<instagram-url>"
|
|
447
|
+
npx ultra-igdl "<instagram-url>" --json
|
|
448
|
+
npx ultra-igdl "<instagram-url>" --download
|
|
449
|
+
npx ultra-igdl "<instagram-url>" --download --output ./my-folder
|
|
450
|
+
npx ultra-igdl "<instagram-url>" --verbose
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
### Batch file (many URLs)
|
|
454
|
+
|
|
455
|
+
Create `urls.txt` — one URL per line. Lines starting with `#` are ignored.
|
|
456
|
+
|
|
457
|
+
```text
|
|
458
|
+
https://www.instagram.com/p/ABC123/
|
|
459
|
+
https://www.instagram.com/reel/DEF456/
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
Run:
|
|
463
|
+
|
|
464
|
+
```bash
|
|
465
|
+
npx ultra-igdl urls.txt --json
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
### All CLI flags
|
|
469
|
+
|
|
470
|
+
| Flag | Short | Description |
|
|
471
|
+
|------|-------|-------------|
|
|
472
|
+
| `--json` | `-j` | Print full API JSON |
|
|
473
|
+
| `--download` | `-d` | Save media files to disk |
|
|
474
|
+
| `--output <dir>` | `-o` | Download folder (default: `./downloads`) |
|
|
475
|
+
| `--verbose` | `-v` | Debug logging |
|
|
476
|
+
| `--help` | `-h` | Show help |
|
|
477
|
+
|
|
478
|
+
### Environment variables (CLI)
|
|
479
|
+
|
|
480
|
+
| Variable | Purpose |
|
|
481
|
+
|----------|---------|
|
|
482
|
+
| `INSTAGRAM_COOKIES` | Full cookie string (`sessionid=...; csrftoken=...; ...`) |
|
|
483
|
+
| `INSTAGRAM_SESSION_ID` | Just the `sessionid` value |
|
|
484
|
+
|
|
485
|
+
### PowerShell tips (Windows)
|
|
486
|
+
|
|
487
|
+
1. **Always quote URLs** that contain `&` (shared links with `?igsh=...&...`).
|
|
488
|
+
2. Setting env vars and running `npx` on the **same line** requires a semicolon:
|
|
489
|
+
|
|
490
|
+
```powershell
|
|
491
|
+
$env:INSTAGRAM_COOKIES = "sessionid=..."; npx ultra-igdl "https://www.instagram.com/p/ABC/" --json
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
3. If you see errors about `npx` or `Unexpected token`, run env and `npx` on **separate lines**.
|
|
495
|
+
|
|
496
|
+
---
|
|
497
|
+
|
|
498
|
+
## 11. JavaScript / TypeScript API
|
|
499
|
+
|
|
500
|
+
### Create an instance
|
|
371
501
|
|
|
372
502
|
```ts
|
|
373
503
|
import { ultraigdl, type ApiResponse, type DownloadResponse } from "ultra-igdl";
|
|
374
504
|
|
|
375
|
-
const ig = new ultraigdl({
|
|
505
|
+
const ig = new ultraigdl({
|
|
506
|
+
cache: true,
|
|
507
|
+
retries: 2,
|
|
508
|
+
cookies: process.env.INSTAGRAM_COOKIES,
|
|
509
|
+
});
|
|
376
510
|
```
|
|
377
511
|
|
|
378
|
-
|
|
379
|
-
|--------|---------|-------------|
|
|
380
|
-
| `download(url)` | `Promise<ApiResponse>` | Full extraction (main method) |
|
|
381
|
-
| `info(url)` | `Promise<ApiResponse>` | Alias of `download` |
|
|
382
|
-
| `validate(url)` | `Promise<{ valid, type?, normalized? }>` | URL check + normalization |
|
|
383
|
-
| `media(url)` | `Promise<Media[] \| ErrorResponse>` | Media array only |
|
|
384
|
-
| `batch(urls)` | `Promise<BatchResult[]>` | Parallel downloads with per-URL timing |
|
|
385
|
-
| `prefetch(url)` | `Promise<ApiResponse>` | Warm cache for `fastMode` |
|
|
386
|
-
| `health()` | `Promise<HealthStatus>` | Cache stats, pool, version |
|
|
387
|
-
| `clearCache()` | `void` | Clear in-memory LRU cache |
|
|
512
|
+
### Methods
|
|
388
513
|
|
|
389
|
-
|
|
514
|
+
| Method | Returns | When to use |
|
|
515
|
+
|--------|---------|-------------|
|
|
516
|
+
| `download(url)` | `Promise<ApiResponse>` | Main method — full result |
|
|
517
|
+
| `info(url)` | `Promise<ApiResponse>` | Same as `download` |
|
|
518
|
+
| `validate(url)` | `Promise<{ valid, type?, normalized? }>` | Check URL before processing |
|
|
519
|
+
| `media(url)` | `Promise<Media[] \| ErrorResponse>` | Only the `media` array |
|
|
520
|
+
| `batch(urls)` | `Promise<BatchResult[]>` | Many URLs at once |
|
|
521
|
+
| `prefetch(url)` | `Promise<ApiResponse>` | Warm cache before `download` (bots) |
|
|
522
|
+
| `health()` | `Promise<HealthStatus>` | Version, cache size, connection pool |
|
|
523
|
+
| `clearCache()` | `void` | Clear in-memory cache |
|
|
390
524
|
|
|
391
|
-
|
|
525
|
+
### TypeScript — narrow success type
|
|
392
526
|
|
|
393
527
|
```ts
|
|
394
528
|
const result = await ig.download(url);
|
|
395
529
|
if (result.code === 200) {
|
|
396
|
-
const
|
|
397
|
-
|
|
530
|
+
const ok = result as DownloadResponse;
|
|
531
|
+
ok.media.forEach((m) => console.log(m.url));
|
|
398
532
|
}
|
|
399
533
|
```
|
|
400
534
|
|
|
401
|
-
###
|
|
535
|
+
### Download files yourself (library)
|
|
536
|
+
|
|
537
|
+
Use `fetch` or any HTTP client on `media[].url`, or use the CLI `--download` flag which handles saving for you.
|
|
538
|
+
|
|
539
|
+
```js
|
|
540
|
+
const res = await fetch(result.media[0].url);
|
|
541
|
+
const buf = Buffer.from(await res.arrayBuffer());
|
|
542
|
+
// write buf to disk with fs
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
**Do not modify** the CDN URL query string — links are signed and may break if edited.
|
|
546
|
+
|
|
547
|
+
### Exported utilities
|
|
402
548
|
|
|
403
549
|
```ts
|
|
404
|
-
import {
|
|
550
|
+
import {
|
|
551
|
+
ultraigdl,
|
|
552
|
+
validateUrl,
|
|
553
|
+
parseInstagramUrl,
|
|
554
|
+
isInstagramUrl,
|
|
555
|
+
PACKAGE_VERSION,
|
|
556
|
+
EXTRACTOR_NAME,
|
|
557
|
+
} from "ultra-igdl";
|
|
405
558
|
```
|
|
406
559
|
|
|
560
|
+
Advanced: `DownloaderCore` is exported for custom integrations.
|
|
561
|
+
|
|
407
562
|
---
|
|
408
563
|
|
|
409
|
-
## Configuration options
|
|
564
|
+
## 12. Configuration options
|
|
410
565
|
|
|
411
|
-
|
|
566
|
+
Pass these to `new ultraigdl({ ... })`:
|
|
567
|
+
|
|
568
|
+
| Option | Default | Description |
|
|
569
|
+
|--------|---------|-------------|
|
|
570
|
+
| `cache` | `true` | Cache responses in memory |
|
|
571
|
+
| `cacheTtlMs` | `300000` (5 min) | Fresh cache lifetime |
|
|
572
|
+
| `staleCacheTtlMs` | `86400000` (24 h) | Serve stale while refreshing |
|
|
573
|
+
| `cacheMaxSize` | `500` | Max cached entries |
|
|
574
|
+
| `timeoutMs` | `8000` | HTTP timeout per request |
|
|
575
|
+
| `retries` | `2` | Retry count on failure |
|
|
576
|
+
| `maxConcurrency` | `100` | Parallel request limit |
|
|
577
|
+
| `userAgentRotation` | `true` | Rotate browser user-agents |
|
|
578
|
+
| `sessionId` | — | Instagram `sessionid` cookie value |
|
|
579
|
+
| `cookies` | — | Full cookie header string |
|
|
580
|
+
| `verbose` | `false` | Extra logging |
|
|
581
|
+
| `fastMode` | `false` | Target ~500 ms response; may return 503 + retry hint |
|
|
582
|
+
| `responseBudgetMs` | — | Max time for `download()` to return |
|
|
583
|
+
| `redis` | — | Custom `RedisAdapter` for shared cache |
|
|
584
|
+
|
|
585
|
+
Example — tuned for a small API server:
|
|
586
|
+
|
|
587
|
+
```js
|
|
412
588
|
const ig = new ultraigdl({
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
cacheTtlMs: 300_000, // 5 min fresh TTL
|
|
416
|
-
staleCacheTtlMs: 86_400_000, // 24h stale-while-revalidate
|
|
417
|
-
cacheMaxSize: 500,
|
|
418
|
-
|
|
419
|
-
// Network
|
|
420
|
-
maxConcurrency: 100,
|
|
589
|
+
cache: true,
|
|
590
|
+
cacheTtlMs: 600_000,
|
|
421
591
|
timeoutMs: 15_000,
|
|
422
592
|
retries: 3,
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
sessionId: "...",
|
|
427
|
-
cookies: "sessionid=...; csrftoken=...; ds_user_id=...",
|
|
428
|
-
|
|
429
|
-
// Low-latency mode (bots that reply in <500ms)
|
|
430
|
-
fastMode: true, // sets responseBudgetMs: 500, retries: 0
|
|
431
|
-
responseBudgetMs: 800,
|
|
593
|
+
cookies: process.env.INSTAGRAM_COOKIES,
|
|
594
|
+
});
|
|
595
|
+
```
|
|
432
596
|
|
|
433
|
-
|
|
434
|
-
redis: myRedisAdapter,
|
|
597
|
+
Example — low-latency bot (may need retry on 503):
|
|
435
598
|
|
|
436
|
-
|
|
437
|
-
});
|
|
599
|
+
```js
|
|
600
|
+
const ig = new ultraigdl({ fastMode: true, cookies: process.env.INSTAGRAM_COOKIES });
|
|
601
|
+
await ig.prefetch(url);
|
|
602
|
+
let result = await ig.download(url);
|
|
603
|
+
if (result.code === 503 && result.retryAfterMs) {
|
|
604
|
+
await new Promise((r) => setTimeout(r, result.retryAfterMs));
|
|
605
|
+
result = await ig.download(url);
|
|
606
|
+
}
|
|
438
607
|
```
|
|
439
608
|
|
|
440
609
|
---
|
|
441
610
|
|
|
442
|
-
##
|
|
611
|
+
## 13. Batch URLs and bots
|
|
443
612
|
|
|
444
|
-
### Batch
|
|
613
|
+
### Batch in code
|
|
445
614
|
|
|
446
|
-
```
|
|
615
|
+
```js
|
|
447
616
|
const results = await ig.batch([
|
|
448
617
|
"https://www.instagram.com/p/A/",
|
|
449
618
|
"https://www.instagram.com/reel/B/",
|
|
450
619
|
]);
|
|
620
|
+
|
|
451
621
|
for (const { url, result, durationMs } of results) {
|
|
452
622
|
console.log(url, result.code, `${durationMs}ms`);
|
|
453
623
|
}
|
|
454
624
|
```
|
|
455
625
|
|
|
456
|
-
###
|
|
626
|
+
### Batch from CLI
|
|
457
627
|
|
|
458
|
-
|
|
459
|
-
const ig = new ultraigdl({ fastMode: true, cookies: "..." });
|
|
628
|
+
Use a `.txt` file ([section 10](#10-command-line-cli--full-guide)).
|
|
460
629
|
|
|
461
|
-
|
|
462
|
-
await ig.prefetch(url);
|
|
463
|
-
|
|
464
|
-
// Often returns from cache within budget
|
|
465
|
-
let result = await ig.download(url);
|
|
466
|
-
if (result.code === 503 && result.retryAfterMs) {
|
|
467
|
-
await new Promise((r) => setTimeout(r, result.retryAfterMs));
|
|
468
|
-
result = await ig.download(url);
|
|
469
|
-
}
|
|
470
|
-
```
|
|
630
|
+
### Redis cache (optional, advanced)
|
|
471
631
|
|
|
472
|
-
|
|
632
|
+
If you run multiple server instances, implement `RedisAdapter`:
|
|
473
633
|
|
|
474
634
|
```ts
|
|
475
635
|
import { ultraigdl, type RedisAdapter } from "ultra-igdl";
|
|
@@ -482,141 +642,86 @@ const redis: RedisAdapter = {
|
|
|
482
642
|
const ig = new ultraigdl({ redis });
|
|
483
643
|
```
|
|
484
644
|
|
|
485
|
-
### Download files to disk (library)
|
|
486
|
-
|
|
487
|
-
Use your own `fetch` on `media[].url`, or the CLI `--download` flag (uses built-in file downloader).
|
|
488
|
-
|
|
489
645
|
---
|
|
490
646
|
|
|
491
|
-
## Error codes
|
|
647
|
+
## 14. Error codes and fixes
|
|
492
648
|
|
|
493
|
-
| Code |
|
|
494
|
-
|
|
495
|
-
| **400** | Invalid URL |
|
|
496
|
-
| **403** | Private
|
|
497
|
-
| **404** |
|
|
498
|
-
| **429** | Rate limited |
|
|
499
|
-
| **500** |
|
|
500
|
-
| **503** |
|
|
649
|
+
| Code | Meaning | What to try |
|
|
650
|
+
|------|---------|-------------|
|
|
651
|
+
| **400** | Invalid URL | Run `validate()`; fix the link |
|
|
652
|
+
| **403** | Private or blocked | Cannot access without permission |
|
|
653
|
+
| **404** | Not found | Post deleted, wrong ID, or expired story |
|
|
654
|
+
| **429** | Rate limited | Wait and slow down; fewer parallel requests |
|
|
655
|
+
| **500** | Server / parse error | Retry; update package; open an issue |
|
|
656
|
+
| **503** | Fast mode: still fetching | Wait `retryAfterMs` and call `download` again |
|
|
501
657
|
| **504** | Timeout | Increase `timeoutMs` |
|
|
502
658
|
|
|
503
|
-
| Symptom | Fix |
|
|
504
|
-
|---------|-----|
|
|
505
|
-
| Carousel returns 1 image | Set `cookies` or `sessionId` |
|
|
506
|
-
| Reel has no MP4 | Add session cookie |
|
|
507
|
-
| CLI `Unexpected token 'npx'` | Use `;` or two lines in PowerShell |
|
|
508
|
-
| `Invalid or unexpected token` on CLI | Run `npm run build`; use published version |
|
|
509
|
-
| Caption has weird dots/lines | Post captions are flattened to one line by design |
|
|
510
|
-
| 403 on CDN URL when downloading | Do not modify signed URL query string |
|
|
511
|
-
|
|
512
659
|
---
|
|
513
660
|
|
|
514
|
-
##
|
|
515
|
-
|
|
516
|
-
| File | Description |
|
|
517
|
-
|------|-------------|
|
|
518
|
-
| [`examples/basic.mjs`](./examples/basic.mjs) | Minimal JSON dump |
|
|
519
|
-
| [`examples/bot-example.ts`](./examples/bot-example.ts) | Generic bot handler |
|
|
520
|
-
| [`examples/express-api.ts`](./examples/express-api.ts) | REST API with Express |
|
|
521
|
-
| [`examples/fastify-api.ts`](./examples/fastify-api.ts) | REST API with Fastify |
|
|
522
|
-
| [`examples/telegram-bot.ts`](./examples/telegram-bot.ts) | Telegram-style handler |
|
|
523
|
-
| [`examples/discord-bot.ts`](./examples/discord-bot.ts) | Discord-style handler |
|
|
524
|
-
| [`examples/cookie-generator.mjs`](./examples/cookie-generator.mjs) | Cookie helper notes |
|
|
525
|
-
|
|
526
|
-
Run locally after build:
|
|
661
|
+
## 15. FAQ and troubleshooting
|
|
527
662
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
node examples/basic.mjs "https://www.instagram.com/p/SHORTCODE/"
|
|
531
|
-
```
|
|
663
|
+
**Q: Carousel only returns one image.**
|
|
664
|
+
A: Add `INSTAGRAM_COOKIES` or `sessionId` ([section 8](#8-instagram-session--why-and-how)).
|
|
532
665
|
|
|
533
|
-
**
|
|
666
|
+
**Q: Reel has no video, only thumbnail.**
|
|
667
|
+
A: Same — use a logged-in session cookie.
|
|
534
668
|
|
|
535
|
-
|
|
669
|
+
**Q: Story returns 404.**
|
|
670
|
+
A: Stories expire after 24 hours, or the URL is wrong. Session is required.
|
|
536
671
|
|
|
537
|
-
|
|
672
|
+
**Q: CLI works on Mac but fails on PowerShell.**
|
|
673
|
+
A: Quote the URL; set env vars on a separate line or use `;` before `npx`.
|
|
538
674
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
├── core/ # downloader orchestration, cache, parser, extractor
|
|
542
|
-
├── extractors/ # post, reel, story, highlight
|
|
543
|
-
├── network/ # undici client, headers, retry, pool, Instagram API
|
|
544
|
-
├── utils/ # captions, carousel, media quality, URLs
|
|
545
|
-
├── cli/ # CLI entry (published as ultra-igdl bin)
|
|
546
|
-
└── types/ # TypeScript definitions
|
|
547
|
-
```
|
|
675
|
+
**Q: Downloaded file from CDN is corrupt or 403.**
|
|
676
|
+
A: Copy the `url` exactly from the API response. Do not strip query parameters.
|
|
548
677
|
|
|
549
|
-
**
|
|
678
|
+
**Q: Caption looks like one long line.**
|
|
679
|
+
A: Post captions are normalized to a single clean line by design (engagement text is in `engagement`, not `caption`).
|
|
550
680
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
3. `window.__additionalDataLoaded` / `_sharedData`
|
|
554
|
-
4. Next.js `__NEXT_DATA__`
|
|
555
|
-
5. GraphQL / CDN discovery in HTML
|
|
556
|
-
6. Regex fallback
|
|
681
|
+
**Q: How do I update?**
|
|
682
|
+
A: `npm update ultra-igdl` or bump version in `package.json` and run `npm install`.
|
|
557
683
|
|
|
558
|
-
|
|
684
|
+
**Q: Does this need an Instagram API key?**
|
|
685
|
+
A: No. It uses the same kind of page parsing and optional session API as a logged-in browser.
|
|
559
686
|
|
|
560
687
|
---
|
|
561
688
|
|
|
562
|
-
##
|
|
689
|
+
## 16. Examples in this repository
|
|
563
690
|
|
|
564
|
-
|
|
565
|
-
git clone https://github.com/your-username/ultra-igdl.git
|
|
566
|
-
cd ultra-igdl
|
|
567
|
-
npm install
|
|
568
|
-
npm run build
|
|
569
|
-
npm test
|
|
570
|
-
npm run test:coverage
|
|
571
|
-
npm run test:stress
|
|
572
|
-
```
|
|
573
|
-
|
|
574
|
-
| Script | Purpose |
|
|
575
|
-
|--------|---------|
|
|
576
|
-
| `npm run build` | Compile ESM + CJS + CLI to `dist/` |
|
|
577
|
-
| `npm test` | Unit + integration tests (mocked HTTP; excludes stress) |
|
|
578
|
-
| `npm run cli -- "<url>" --json` | Run CLI from source tree |
|
|
579
|
-
| `npm run lint` | Typecheck |
|
|
691
|
+
After cloning, build once: `npm run build`.
|
|
580
692
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
693
|
+
| File | What it shows |
|
|
694
|
+
|------|----------------|
|
|
695
|
+
| [`examples/basic.mjs`](./examples/basic.mjs) | Minimal JSON output |
|
|
696
|
+
| [`examples/bot-example.ts`](./examples/bot-example.ts) | Generic bot handler |
|
|
697
|
+
| [`examples/express-api.ts`](./examples/express-api.ts) | REST API with Express |
|
|
698
|
+
| [`examples/fastify-api.ts`](./examples/fastify-api.ts) | REST API with Fastify |
|
|
699
|
+
| [`examples/telegram-bot.ts`](./examples/telegram-bot.ts) | Telegram-style flow |
|
|
700
|
+
| [`examples/discord-bot.ts`](./examples/discord-bot.ts) | Discord-style flow |
|
|
701
|
+
| [`examples/cookie-generator.mjs`](./examples/cookie-generator.mjs) | Cookie setup notes |
|
|
584
702
|
|
|
585
|
-
|
|
703
|
+
Run basic example:
|
|
586
704
|
|
|
587
705
|
```bash
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
# 2. Set author/repository in package.json (your GitHub username)
|
|
592
|
-
|
|
593
|
-
# 3. Dry run — only dist/, README, LICENSE should be listed
|
|
594
|
-
npm pack --dry-run
|
|
595
|
-
|
|
596
|
-
# 4. Publish (runs build + tests via prepublishOnly)
|
|
597
|
-
npm publish
|
|
706
|
+
npm run build
|
|
707
|
+
node examples/basic.mjs "https://www.instagram.com/p/SHORTCODE/"
|
|
598
708
|
```
|
|
599
709
|
|
|
600
|
-
|
|
710
|
+
---
|
|
601
711
|
|
|
602
|
-
|
|
603
|
-
npm install ultra-igdl
|
|
604
|
-
```
|
|
712
|
+
## 17. Legal and privacy
|
|
605
713
|
|
|
606
|
-
**
|
|
714
|
+
- **Not affiliated** with Instagram or Meta.
|
|
715
|
+
- You must follow **Instagram’s Terms of Use** and your local laws. Only download content you are allowed to use.
|
|
716
|
+
- **Session cookies are credentials** — never commit them, share them publicly, or log them in production.
|
|
717
|
+
- CDN URLs are **temporary signed links** — download soon; do not alter the URL.
|
|
607
718
|
|
|
608
719
|
---
|
|
609
720
|
|
|
610
|
-
##
|
|
721
|
+
## 18. License
|
|
611
722
|
|
|
612
|
-
|
|
613
|
-
- You are responsible for complying with Instagram's Terms of Use and applicable laws.
|
|
614
|
-
- Only download content you have the right to access and use.
|
|
615
|
-
- Session cookies are credentials — treat them like passwords.
|
|
616
|
-
- CDN URLs are **signed** and expire; download promptly and do not strip query parameters.
|
|
723
|
+
[MIT](./LICENSE) — free to use with attribution.
|
|
617
724
|
|
|
618
725
|
---
|
|
619
726
|
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
[MIT](./LICENSE) © 2026 ultra-igdl contributors
|
|
727
|
+
**Need help?** Open an issue: [github.com/WH173-5P1D3R/ultra-igdl/issues](https://github.com/WH173-5P1D3R/ultra-igdl/issues)
|