reelscribe 1.0.0
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/LICENSE +21 -0
- package/README.md +182 -0
- package/dist/index.d.mts +178 -0
- package/dist/index.d.ts +178 -0
- package/dist/index.js +141 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +113 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ReelScribe
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# ReelScribe Node.js SDK
|
|
2
|
+
|
|
3
|
+
Official Node.js/TypeScript client for the [ReelScribe](https://www.reelscribe.app) API — transcribe Instagram Reels, TikTok videos, and YouTube Shorts programmatically.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/reelscribe)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install reelscribe
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import { ReelScribe } from 'reelscribe'
|
|
18
|
+
|
|
19
|
+
const rs = new ReelScribe('rs_your_api_key')
|
|
20
|
+
|
|
21
|
+
// Submit a video for transcription
|
|
22
|
+
const { requestId } = await rs.transcribe({
|
|
23
|
+
url: 'https://www.instagram.com/reel/ABC123/',
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
// Poll for the result
|
|
27
|
+
const transcription = await rs.getTranscription({ requestId })
|
|
28
|
+
console.log(transcription.transcription)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
> Get your API key from the [ReelScribe dashboard](https://www.reelscribe.app/api).
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
### Transcribe a Video
|
|
36
|
+
|
|
37
|
+
Submit an Instagram Reel, TikTok video, or YouTube Short for transcription. Costs 1 credit per request.
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
const result = await rs.transcribe({
|
|
41
|
+
url: 'https://www.youtube.com/shorts/dQw4w9WgXcQ',
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
console.log(result.requestId) // use this to check status
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
#### With Webhook
|
|
48
|
+
|
|
49
|
+
Instead of polling, provide a `resumeUrl` to receive a POST when the transcription is ready:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
const result = await rs.transcribe({
|
|
53
|
+
url: 'https://www.tiktok.com/@user/video/1234567890',
|
|
54
|
+
resumeUrl: 'https://your-server.com/webhook',
|
|
55
|
+
})
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Your server will receive the full transcription result as a POST request. See the [webhook docs](https://www.reelscribe.app/api) for the payload format.
|
|
59
|
+
|
|
60
|
+
### Get a Transcription
|
|
61
|
+
|
|
62
|
+
Retrieve a transcription by the `requestId` returned from `transcribe()`:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
const t = await rs.getTranscription({ requestId: '550e8400-...' })
|
|
66
|
+
|
|
67
|
+
console.log(t.status) // 'completed'
|
|
68
|
+
console.log(t.transcription) // 'The full transcription text...'
|
|
69
|
+
console.log(t.caption) // Original post caption
|
|
70
|
+
console.log(t.hashtags) // ['tag1', 'tag2']
|
|
71
|
+
console.log(t.stats) // { likes: 1234, views: 56789, comments: 42 }
|
|
72
|
+
console.log(t.segments) // [{ start: 0, end: 2.5, text: 'Hello...' }]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Or fetch by Convex document ID:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
const t = await rs.getTranscription({ id: 'abc123' })
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### List Transcriptions
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
// All transcriptions
|
|
85
|
+
const { transcriptions, total } = await rs.listTranscriptions()
|
|
86
|
+
|
|
87
|
+
// Filter by status
|
|
88
|
+
const completed = await rs.listTranscriptions({ status: 'completed' })
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Check Credits
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
const credits = await rs.getCredits()
|
|
95
|
+
|
|
96
|
+
console.log(credits.credits) // 450
|
|
97
|
+
console.log(credits.tier) // 'creator'
|
|
98
|
+
console.log(credits.subscriptionStatus) // 'active'
|
|
99
|
+
console.log(credits.storageUsed) // 42
|
|
100
|
+
console.log(credits.storageLimit) // 100
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Settings
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
// Read settings
|
|
107
|
+
const settings = await rs.getSettings()
|
|
108
|
+
console.log(settings.autoPruneStorage) // true
|
|
109
|
+
|
|
110
|
+
// Update settings
|
|
111
|
+
await rs.updateSettings({ autoPruneStorage: false })
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Health Check
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
const health = await rs.health()
|
|
118
|
+
console.log(health.healthy) // true
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Error Handling
|
|
122
|
+
|
|
123
|
+
All API errors throw a `ReelScribeError` with a machine-readable `code` and HTTP `status`:
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import { ReelScribe, ReelScribeError } from 'reelscribe'
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
await rs.transcribe({ url: 'https://www.instagram.com/reel/ABC123/' })
|
|
130
|
+
} catch (err) {
|
|
131
|
+
if (err instanceof ReelScribeError) {
|
|
132
|
+
console.log(err.code) // 'INSUFFICIENT_CREDITS'
|
|
133
|
+
console.log(err.status) // 402
|
|
134
|
+
console.log(err.message) // 'You need at least 1 credit'
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
| Code | Status | Description |
|
|
140
|
+
|------|--------|-------------|
|
|
141
|
+
| `INVALID_REQUEST` | 400 | Bad request body or missing fields |
|
|
142
|
+
| `INVALID_URL` | 400 | Unsupported video platform |
|
|
143
|
+
| `UNAUTHORIZED` | 401 | Missing or invalid API key |
|
|
144
|
+
| `INSUFFICIENT_CREDITS` | 402 | No credits remaining |
|
|
145
|
+
| `STORAGE_LIMIT` | 403 | Transcript storage full |
|
|
146
|
+
| `NOT_FOUND` | 404 | Transcription not found |
|
|
147
|
+
| `SERVICE_ERROR` | 503 | Transcription service unavailable (credit refunded) |
|
|
148
|
+
|
|
149
|
+
## Configuration
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
const rs = new ReelScribe('rs_your_api_key', {
|
|
153
|
+
// Override the base URL (useful for testing)
|
|
154
|
+
baseUrl: 'https://staging.reelscribe.app',
|
|
155
|
+
// Provide a custom fetch implementation
|
|
156
|
+
fetch: myCustomFetch,
|
|
157
|
+
})
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Supported Platforms
|
|
161
|
+
|
|
162
|
+
| Platform | Example URL |
|
|
163
|
+
|----------|-------------|
|
|
164
|
+
| Instagram Reels | `https://www.instagram.com/reel/ABC123/` |
|
|
165
|
+
| TikTok Videos | `https://www.tiktok.com/@user/video/1234567890` |
|
|
166
|
+
| YouTube Shorts | `https://www.youtube.com/shorts/dQw4w9WgXcQ` |
|
|
167
|
+
| YouTube Videos | `https://www.youtube.com/watch?v=dQw4w9WgXcQ` |
|
|
168
|
+
|
|
169
|
+
## Requirements
|
|
170
|
+
|
|
171
|
+
- Node.js 18+ (uses native `fetch`)
|
|
172
|
+
- A [ReelScribe](https://www.reelscribe.app) account with API access
|
|
173
|
+
|
|
174
|
+
## Links
|
|
175
|
+
|
|
176
|
+
- [ReelScribe](https://www.reelscribe.app) — Video transcription for content creators
|
|
177
|
+
- [API Documentation](https://www.reelscribe.app/api) — Full endpoint reference & API key management
|
|
178
|
+
- [Pricing](https://www.reelscribe.app/pricing) — Plans starting at $9.99/month
|
|
179
|
+
|
|
180
|
+
## License
|
|
181
|
+
|
|
182
|
+
[MIT](LICENSE)
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/** Supported video platforms. */
|
|
2
|
+
type Platform = 'instagram' | 'tiktok' | 'youtube';
|
|
3
|
+
/** Transcription lifecycle status. */
|
|
4
|
+
type TranscriptionStatus = 'submitted' | 'processing' | 'completed' | 'failed' | 'cancelled';
|
|
5
|
+
/** Subscription tier. */
|
|
6
|
+
type Tier = 'free' | 'creator' | 'agency' | 'enterprise';
|
|
7
|
+
interface TranscribeOptions {
|
|
8
|
+
/** Instagram, TikTok, or YouTube URL (max 2048 chars). */
|
|
9
|
+
url: string;
|
|
10
|
+
/** Optional HTTPS webhook URL — receives a POST when the job finishes. */
|
|
11
|
+
resumeUrl?: string;
|
|
12
|
+
}
|
|
13
|
+
interface ListTranscriptionsOptions {
|
|
14
|
+
/** Filter by status. */
|
|
15
|
+
status?: TranscriptionStatus;
|
|
16
|
+
}
|
|
17
|
+
interface GetTranscriptionOptions {
|
|
18
|
+
/** Convex document ID. */
|
|
19
|
+
id?: string;
|
|
20
|
+
/** The requestId returned from `transcribe()`. */
|
|
21
|
+
requestId?: string;
|
|
22
|
+
}
|
|
23
|
+
interface UpdateSettingsOptions {
|
|
24
|
+
/** Enable or disable automatic storage pruning. */
|
|
25
|
+
autoPruneStorage: boolean;
|
|
26
|
+
}
|
|
27
|
+
interface TranscribeResult {
|
|
28
|
+
requestId: string;
|
|
29
|
+
status: 'submitted';
|
|
30
|
+
message: string;
|
|
31
|
+
}
|
|
32
|
+
interface DuplicateResult {
|
|
33
|
+
duplicate: true;
|
|
34
|
+
message: string;
|
|
35
|
+
transcription: {
|
|
36
|
+
id: string;
|
|
37
|
+
status: TranscriptionStatus;
|
|
38
|
+
transcription: string | null;
|
|
39
|
+
createdAt: number;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
interface VideoStats {
|
|
43
|
+
likes: number | null;
|
|
44
|
+
views: number | null;
|
|
45
|
+
comments: number | null;
|
|
46
|
+
}
|
|
47
|
+
interface Segment {
|
|
48
|
+
start: number;
|
|
49
|
+
end: number;
|
|
50
|
+
text: string;
|
|
51
|
+
}
|
|
52
|
+
interface Transcription {
|
|
53
|
+
id: string;
|
|
54
|
+
requestId: string | null;
|
|
55
|
+
url: string;
|
|
56
|
+
platform: Platform | null;
|
|
57
|
+
status: TranscriptionStatus;
|
|
58
|
+
transcription: string | null;
|
|
59
|
+
createdAt: number;
|
|
60
|
+
completedAt: number | null;
|
|
61
|
+
caption: string | null;
|
|
62
|
+
hashtags: string[] | null;
|
|
63
|
+
mentions: string[] | null;
|
|
64
|
+
owner: string | null;
|
|
65
|
+
duration: number | null;
|
|
66
|
+
stats: VideoStats | null;
|
|
67
|
+
segments: Segment[] | null;
|
|
68
|
+
thumbnailUrl: string | null;
|
|
69
|
+
videoTimestamp: string | null;
|
|
70
|
+
errorMessage: string | null;
|
|
71
|
+
errorType: string | null;
|
|
72
|
+
}
|
|
73
|
+
interface TranscriptionList {
|
|
74
|
+
transcriptions: Transcription[];
|
|
75
|
+
total: number;
|
|
76
|
+
}
|
|
77
|
+
interface Credits {
|
|
78
|
+
credits: number;
|
|
79
|
+
tier: Tier;
|
|
80
|
+
subscriptionStatus: string | null;
|
|
81
|
+
storageUsed: number;
|
|
82
|
+
storageLimit: number;
|
|
83
|
+
}
|
|
84
|
+
interface Settings {
|
|
85
|
+
autoPruneStorage: boolean;
|
|
86
|
+
}
|
|
87
|
+
interface HealthCheck {
|
|
88
|
+
healthy: boolean;
|
|
89
|
+
timestamp: string;
|
|
90
|
+
}
|
|
91
|
+
interface ApiErrorBody {
|
|
92
|
+
code: string;
|
|
93
|
+
message: string;
|
|
94
|
+
status: number;
|
|
95
|
+
}
|
|
96
|
+
interface ReelScribeOptions {
|
|
97
|
+
/** Override the base URL (default: `https://www.reelscribe.app`). */
|
|
98
|
+
baseUrl?: string;
|
|
99
|
+
/** Override the global `fetch` implementation. */
|
|
100
|
+
fetch?: typeof globalThis.fetch;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* ReelScribe API client.
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```ts
|
|
108
|
+
* const rs = new ReelScribe('rs_your_api_key')
|
|
109
|
+
* const { requestId } = await rs.transcribe({ url: 'https://www.instagram.com/reel/ABC123/' })
|
|
110
|
+
* const result = await rs.getTranscription({ requestId })
|
|
111
|
+
* ```
|
|
112
|
+
*
|
|
113
|
+
* @see https://www.reelscribe.app/api — full API documentation
|
|
114
|
+
*/
|
|
115
|
+
declare class ReelScribe {
|
|
116
|
+
private readonly apiKey;
|
|
117
|
+
private readonly baseUrl;
|
|
118
|
+
private readonly _fetch;
|
|
119
|
+
constructor(apiKey: string, options?: ReelScribeOptions);
|
|
120
|
+
private request;
|
|
121
|
+
/**
|
|
122
|
+
* Submit a video URL for transcription. Costs 1 credit.
|
|
123
|
+
*
|
|
124
|
+
* If the video was already transcribed, returns a `DuplicateResult` instead.
|
|
125
|
+
*
|
|
126
|
+
* @see https://www.reelscribe.app/api — POST /v1/transcribe
|
|
127
|
+
*/
|
|
128
|
+
transcribe(options: TranscribeOptions): Promise<TranscribeResult | DuplicateResult>;
|
|
129
|
+
/**
|
|
130
|
+
* Fetch a single transcription by Convex document ID or requestId.
|
|
131
|
+
*
|
|
132
|
+
* @see https://www.reelscribe.app/api — GET /v1/transcriptions?id=...
|
|
133
|
+
*/
|
|
134
|
+
getTranscription(options: GetTranscriptionOptions): Promise<Transcription>;
|
|
135
|
+
/**
|
|
136
|
+
* List all your transcriptions, optionally filtered by status.
|
|
137
|
+
*
|
|
138
|
+
* @see https://www.reelscribe.app/api — GET /v1/transcriptions
|
|
139
|
+
*/
|
|
140
|
+
listTranscriptions(options?: ListTranscriptionsOptions): Promise<TranscriptionList>;
|
|
141
|
+
/**
|
|
142
|
+
* Check your credit balance, subscription tier, and storage usage.
|
|
143
|
+
*
|
|
144
|
+
* @see https://www.reelscribe.app/api — GET /v1/credits
|
|
145
|
+
*/
|
|
146
|
+
getCredits(): Promise<Credits>;
|
|
147
|
+
/**
|
|
148
|
+
* Get your current settings.
|
|
149
|
+
*
|
|
150
|
+
* @see https://www.reelscribe.app/api — GET /v1/settings
|
|
151
|
+
*/
|
|
152
|
+
getSettings(): Promise<Settings>;
|
|
153
|
+
/**
|
|
154
|
+
* Update your settings (e.g. auto-prune storage).
|
|
155
|
+
*
|
|
156
|
+
* @see https://www.reelscribe.app/api — PATCH /v1/settings
|
|
157
|
+
*/
|
|
158
|
+
updateSettings(options: UpdateSettingsOptions): Promise<Settings>;
|
|
159
|
+
/**
|
|
160
|
+
* Check whether the API is healthy. Does not require authentication.
|
|
161
|
+
*
|
|
162
|
+
* @see https://www.reelscribe.app/api — GET /v1/health
|
|
163
|
+
*/
|
|
164
|
+
health(): Promise<HealthCheck>;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Error thrown when the ReelScribe API returns a non-2xx response.
|
|
169
|
+
*/
|
|
170
|
+
declare class ReelScribeError extends Error {
|
|
171
|
+
/** Machine-readable error code (e.g. `INSUFFICIENT_CREDITS`). */
|
|
172
|
+
readonly code: string;
|
|
173
|
+
/** HTTP status code. */
|
|
174
|
+
readonly status: number;
|
|
175
|
+
constructor(body: ApiErrorBody);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export { type ApiErrorBody, type Credits, type DuplicateResult, type GetTranscriptionOptions, type HealthCheck, type ListTranscriptionsOptions, type Platform, ReelScribe, ReelScribeError, type ReelScribeOptions, type Segment, type Settings, type Tier, type TranscribeOptions, type TranscribeResult, type Transcription, type TranscriptionList, type TranscriptionStatus, type UpdateSettingsOptions, type VideoStats };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/** Supported video platforms. */
|
|
2
|
+
type Platform = 'instagram' | 'tiktok' | 'youtube';
|
|
3
|
+
/** Transcription lifecycle status. */
|
|
4
|
+
type TranscriptionStatus = 'submitted' | 'processing' | 'completed' | 'failed' | 'cancelled';
|
|
5
|
+
/** Subscription tier. */
|
|
6
|
+
type Tier = 'free' | 'creator' | 'agency' | 'enterprise';
|
|
7
|
+
interface TranscribeOptions {
|
|
8
|
+
/** Instagram, TikTok, or YouTube URL (max 2048 chars). */
|
|
9
|
+
url: string;
|
|
10
|
+
/** Optional HTTPS webhook URL — receives a POST when the job finishes. */
|
|
11
|
+
resumeUrl?: string;
|
|
12
|
+
}
|
|
13
|
+
interface ListTranscriptionsOptions {
|
|
14
|
+
/** Filter by status. */
|
|
15
|
+
status?: TranscriptionStatus;
|
|
16
|
+
}
|
|
17
|
+
interface GetTranscriptionOptions {
|
|
18
|
+
/** Convex document ID. */
|
|
19
|
+
id?: string;
|
|
20
|
+
/** The requestId returned from `transcribe()`. */
|
|
21
|
+
requestId?: string;
|
|
22
|
+
}
|
|
23
|
+
interface UpdateSettingsOptions {
|
|
24
|
+
/** Enable or disable automatic storage pruning. */
|
|
25
|
+
autoPruneStorage: boolean;
|
|
26
|
+
}
|
|
27
|
+
interface TranscribeResult {
|
|
28
|
+
requestId: string;
|
|
29
|
+
status: 'submitted';
|
|
30
|
+
message: string;
|
|
31
|
+
}
|
|
32
|
+
interface DuplicateResult {
|
|
33
|
+
duplicate: true;
|
|
34
|
+
message: string;
|
|
35
|
+
transcription: {
|
|
36
|
+
id: string;
|
|
37
|
+
status: TranscriptionStatus;
|
|
38
|
+
transcription: string | null;
|
|
39
|
+
createdAt: number;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
interface VideoStats {
|
|
43
|
+
likes: number | null;
|
|
44
|
+
views: number | null;
|
|
45
|
+
comments: number | null;
|
|
46
|
+
}
|
|
47
|
+
interface Segment {
|
|
48
|
+
start: number;
|
|
49
|
+
end: number;
|
|
50
|
+
text: string;
|
|
51
|
+
}
|
|
52
|
+
interface Transcription {
|
|
53
|
+
id: string;
|
|
54
|
+
requestId: string | null;
|
|
55
|
+
url: string;
|
|
56
|
+
platform: Platform | null;
|
|
57
|
+
status: TranscriptionStatus;
|
|
58
|
+
transcription: string | null;
|
|
59
|
+
createdAt: number;
|
|
60
|
+
completedAt: number | null;
|
|
61
|
+
caption: string | null;
|
|
62
|
+
hashtags: string[] | null;
|
|
63
|
+
mentions: string[] | null;
|
|
64
|
+
owner: string | null;
|
|
65
|
+
duration: number | null;
|
|
66
|
+
stats: VideoStats | null;
|
|
67
|
+
segments: Segment[] | null;
|
|
68
|
+
thumbnailUrl: string | null;
|
|
69
|
+
videoTimestamp: string | null;
|
|
70
|
+
errorMessage: string | null;
|
|
71
|
+
errorType: string | null;
|
|
72
|
+
}
|
|
73
|
+
interface TranscriptionList {
|
|
74
|
+
transcriptions: Transcription[];
|
|
75
|
+
total: number;
|
|
76
|
+
}
|
|
77
|
+
interface Credits {
|
|
78
|
+
credits: number;
|
|
79
|
+
tier: Tier;
|
|
80
|
+
subscriptionStatus: string | null;
|
|
81
|
+
storageUsed: number;
|
|
82
|
+
storageLimit: number;
|
|
83
|
+
}
|
|
84
|
+
interface Settings {
|
|
85
|
+
autoPruneStorage: boolean;
|
|
86
|
+
}
|
|
87
|
+
interface HealthCheck {
|
|
88
|
+
healthy: boolean;
|
|
89
|
+
timestamp: string;
|
|
90
|
+
}
|
|
91
|
+
interface ApiErrorBody {
|
|
92
|
+
code: string;
|
|
93
|
+
message: string;
|
|
94
|
+
status: number;
|
|
95
|
+
}
|
|
96
|
+
interface ReelScribeOptions {
|
|
97
|
+
/** Override the base URL (default: `https://www.reelscribe.app`). */
|
|
98
|
+
baseUrl?: string;
|
|
99
|
+
/** Override the global `fetch` implementation. */
|
|
100
|
+
fetch?: typeof globalThis.fetch;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* ReelScribe API client.
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```ts
|
|
108
|
+
* const rs = new ReelScribe('rs_your_api_key')
|
|
109
|
+
* const { requestId } = await rs.transcribe({ url: 'https://www.instagram.com/reel/ABC123/' })
|
|
110
|
+
* const result = await rs.getTranscription({ requestId })
|
|
111
|
+
* ```
|
|
112
|
+
*
|
|
113
|
+
* @see https://www.reelscribe.app/api — full API documentation
|
|
114
|
+
*/
|
|
115
|
+
declare class ReelScribe {
|
|
116
|
+
private readonly apiKey;
|
|
117
|
+
private readonly baseUrl;
|
|
118
|
+
private readonly _fetch;
|
|
119
|
+
constructor(apiKey: string, options?: ReelScribeOptions);
|
|
120
|
+
private request;
|
|
121
|
+
/**
|
|
122
|
+
* Submit a video URL for transcription. Costs 1 credit.
|
|
123
|
+
*
|
|
124
|
+
* If the video was already transcribed, returns a `DuplicateResult` instead.
|
|
125
|
+
*
|
|
126
|
+
* @see https://www.reelscribe.app/api — POST /v1/transcribe
|
|
127
|
+
*/
|
|
128
|
+
transcribe(options: TranscribeOptions): Promise<TranscribeResult | DuplicateResult>;
|
|
129
|
+
/**
|
|
130
|
+
* Fetch a single transcription by Convex document ID or requestId.
|
|
131
|
+
*
|
|
132
|
+
* @see https://www.reelscribe.app/api — GET /v1/transcriptions?id=...
|
|
133
|
+
*/
|
|
134
|
+
getTranscription(options: GetTranscriptionOptions): Promise<Transcription>;
|
|
135
|
+
/**
|
|
136
|
+
* List all your transcriptions, optionally filtered by status.
|
|
137
|
+
*
|
|
138
|
+
* @see https://www.reelscribe.app/api — GET /v1/transcriptions
|
|
139
|
+
*/
|
|
140
|
+
listTranscriptions(options?: ListTranscriptionsOptions): Promise<TranscriptionList>;
|
|
141
|
+
/**
|
|
142
|
+
* Check your credit balance, subscription tier, and storage usage.
|
|
143
|
+
*
|
|
144
|
+
* @see https://www.reelscribe.app/api — GET /v1/credits
|
|
145
|
+
*/
|
|
146
|
+
getCredits(): Promise<Credits>;
|
|
147
|
+
/**
|
|
148
|
+
* Get your current settings.
|
|
149
|
+
*
|
|
150
|
+
* @see https://www.reelscribe.app/api — GET /v1/settings
|
|
151
|
+
*/
|
|
152
|
+
getSettings(): Promise<Settings>;
|
|
153
|
+
/**
|
|
154
|
+
* Update your settings (e.g. auto-prune storage).
|
|
155
|
+
*
|
|
156
|
+
* @see https://www.reelscribe.app/api — PATCH /v1/settings
|
|
157
|
+
*/
|
|
158
|
+
updateSettings(options: UpdateSettingsOptions): Promise<Settings>;
|
|
159
|
+
/**
|
|
160
|
+
* Check whether the API is healthy. Does not require authentication.
|
|
161
|
+
*
|
|
162
|
+
* @see https://www.reelscribe.app/api — GET /v1/health
|
|
163
|
+
*/
|
|
164
|
+
health(): Promise<HealthCheck>;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Error thrown when the ReelScribe API returns a non-2xx response.
|
|
169
|
+
*/
|
|
170
|
+
declare class ReelScribeError extends Error {
|
|
171
|
+
/** Machine-readable error code (e.g. `INSUFFICIENT_CREDITS`). */
|
|
172
|
+
readonly code: string;
|
|
173
|
+
/** HTTP status code. */
|
|
174
|
+
readonly status: number;
|
|
175
|
+
constructor(body: ApiErrorBody);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export { type ApiErrorBody, type Credits, type DuplicateResult, type GetTranscriptionOptions, type HealthCheck, type ListTranscriptionsOptions, type Platform, ReelScribe, ReelScribeError, type ReelScribeOptions, type Segment, type Settings, type Tier, type TranscribeOptions, type TranscribeResult, type Transcription, type TranscriptionList, type TranscriptionStatus, type UpdateSettingsOptions, type VideoStats };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
ReelScribe: () => ReelScribe,
|
|
24
|
+
ReelScribeError: () => ReelScribeError
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(index_exports);
|
|
27
|
+
|
|
28
|
+
// src/errors.ts
|
|
29
|
+
var ReelScribeError = class extends Error {
|
|
30
|
+
constructor(body) {
|
|
31
|
+
super(body.message);
|
|
32
|
+
this.name = "ReelScribeError";
|
|
33
|
+
this.code = body.code;
|
|
34
|
+
this.status = body.status;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// src/client.ts
|
|
39
|
+
var DEFAULT_BASE_URL = "https://www.reelscribe.app";
|
|
40
|
+
var ReelScribe = class {
|
|
41
|
+
constructor(apiKey, options) {
|
|
42
|
+
if (!apiKey) throw new Error("An API key is required. Get one at https://www.reelscribe.app/api");
|
|
43
|
+
this.apiKey = apiKey;
|
|
44
|
+
this.baseUrl = (options?.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
45
|
+
this._fetch = options?.fetch ?? globalThis.fetch;
|
|
46
|
+
}
|
|
47
|
+
// -------------------------------------------------------------------------
|
|
48
|
+
// Internal helpers
|
|
49
|
+
// -------------------------------------------------------------------------
|
|
50
|
+
async request(method, path, body) {
|
|
51
|
+
const url = `${this.baseUrl}/v1/${path}`;
|
|
52
|
+
const headers = {
|
|
53
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
54
|
+
"Content-Type": "application/json"
|
|
55
|
+
};
|
|
56
|
+
const res = await this._fetch(url, {
|
|
57
|
+
method,
|
|
58
|
+
headers,
|
|
59
|
+
body: body ? JSON.stringify(body) : void 0
|
|
60
|
+
});
|
|
61
|
+
const json = await res.json();
|
|
62
|
+
if (!res.ok) {
|
|
63
|
+
throw new ReelScribeError(json.error ?? { code: "UNKNOWN", message: res.statusText, status: res.status });
|
|
64
|
+
}
|
|
65
|
+
return json;
|
|
66
|
+
}
|
|
67
|
+
// -------------------------------------------------------------------------
|
|
68
|
+
// Public methods
|
|
69
|
+
// -------------------------------------------------------------------------
|
|
70
|
+
/**
|
|
71
|
+
* Submit a video URL for transcription. Costs 1 credit.
|
|
72
|
+
*
|
|
73
|
+
* If the video was already transcribed, returns a `DuplicateResult` instead.
|
|
74
|
+
*
|
|
75
|
+
* @see https://www.reelscribe.app/api — POST /v1/transcribe
|
|
76
|
+
*/
|
|
77
|
+
async transcribe(options) {
|
|
78
|
+
return this.request("POST", "transcribe", options);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Fetch a single transcription by Convex document ID or requestId.
|
|
82
|
+
*
|
|
83
|
+
* @see https://www.reelscribe.app/api — GET /v1/transcriptions?id=...
|
|
84
|
+
*/
|
|
85
|
+
async getTranscription(options) {
|
|
86
|
+
const params = new URLSearchParams();
|
|
87
|
+
if (options.id) params.set("id", options.id);
|
|
88
|
+
if (options.requestId) params.set("requestId", options.requestId);
|
|
89
|
+
return this.request("GET", `transcriptions?${params}`);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* List all your transcriptions, optionally filtered by status.
|
|
93
|
+
*
|
|
94
|
+
* @see https://www.reelscribe.app/api — GET /v1/transcriptions
|
|
95
|
+
*/
|
|
96
|
+
async listTranscriptions(options) {
|
|
97
|
+
const params = new URLSearchParams();
|
|
98
|
+
if (options?.status) params.set("status", options.status);
|
|
99
|
+
const qs = params.toString();
|
|
100
|
+
return this.request("GET", `transcriptions${qs ? `?${qs}` : ""}`);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Check your credit balance, subscription tier, and storage usage.
|
|
104
|
+
*
|
|
105
|
+
* @see https://www.reelscribe.app/api — GET /v1/credits
|
|
106
|
+
*/
|
|
107
|
+
async getCredits() {
|
|
108
|
+
return this.request("GET", "credits");
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get your current settings.
|
|
112
|
+
*
|
|
113
|
+
* @see https://www.reelscribe.app/api — GET /v1/settings
|
|
114
|
+
*/
|
|
115
|
+
async getSettings() {
|
|
116
|
+
return this.request("GET", "settings");
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Update your settings (e.g. auto-prune storage).
|
|
120
|
+
*
|
|
121
|
+
* @see https://www.reelscribe.app/api — PATCH /v1/settings
|
|
122
|
+
*/
|
|
123
|
+
async updateSettings(options) {
|
|
124
|
+
return this.request("PATCH", "settings", options);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Check whether the API is healthy. Does not require authentication.
|
|
128
|
+
*
|
|
129
|
+
* @see https://www.reelscribe.app/api — GET /v1/health
|
|
130
|
+
*/
|
|
131
|
+
async health() {
|
|
132
|
+
const res = await this._fetch(`${this.baseUrl}/v1/health`);
|
|
133
|
+
return res.json();
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
137
|
+
0 && (module.exports = {
|
|
138
|
+
ReelScribe,
|
|
139
|
+
ReelScribeError
|
|
140
|
+
});
|
|
141
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/client.ts"],"sourcesContent":["export { ReelScribe } from './client'\nexport { ReelScribeError } from './errors'\nexport type {\n ApiErrorBody,\n Credits,\n DuplicateResult,\n GetTranscriptionOptions,\n HealthCheck,\n ListTranscriptionsOptions,\n Platform,\n ReelScribeOptions,\n Segment,\n Settings,\n Tier,\n TranscribeOptions,\n TranscribeResult,\n Transcription,\n TranscriptionList,\n TranscriptionStatus,\n UpdateSettingsOptions,\n VideoStats,\n} from './types'\n","import type { ApiErrorBody } from './types'\n\n/**\n * Error thrown when the ReelScribe API returns a non-2xx response.\n */\nexport class ReelScribeError extends Error {\n /** Machine-readable error code (e.g. `INSUFFICIENT_CREDITS`). */\n readonly code: string\n /** HTTP status code. */\n readonly status: number\n\n constructor(body: ApiErrorBody) {\n super(body.message)\n this.name = 'ReelScribeError'\n this.code = body.code\n this.status = body.status\n }\n}\n","import { ReelScribeError } from './errors'\nimport type {\n Credits,\n DuplicateResult,\n GetTranscriptionOptions,\n HealthCheck,\n ListTranscriptionsOptions,\n ReelScribeOptions,\n Settings,\n TranscribeOptions,\n TranscribeResult,\n Transcription,\n TranscriptionList,\n UpdateSettingsOptions,\n} from './types'\n\nconst DEFAULT_BASE_URL = 'https://www.reelscribe.app'\n\n/**\n * ReelScribe API client.\n *\n * @example\n * ```ts\n * const rs = new ReelScribe('rs_your_api_key')\n * const { requestId } = await rs.transcribe({ url: 'https://www.instagram.com/reel/ABC123/' })\n * const result = await rs.getTranscription({ requestId })\n * ```\n *\n * @see https://www.reelscribe.app/api — full API documentation\n */\nexport class ReelScribe {\n private readonly apiKey: string\n private readonly baseUrl: string\n private readonly _fetch: typeof globalThis.fetch\n\n constructor(apiKey: string, options?: ReelScribeOptions) {\n if (!apiKey) throw new Error('An API key is required. Get one at https://www.reelscribe.app/api')\n this.apiKey = apiKey\n this.baseUrl = (options?.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '')\n this._fetch = options?.fetch ?? globalThis.fetch\n }\n\n // -------------------------------------------------------------------------\n // Internal helpers\n // -------------------------------------------------------------------------\n\n private async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}/v1/${path}`\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n }\n\n const res = await this._fetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n })\n\n const json = await res.json()\n\n if (!res.ok) {\n throw new ReelScribeError(json.error ?? { code: 'UNKNOWN', message: res.statusText, status: res.status })\n }\n\n return json as T\n }\n\n // -------------------------------------------------------------------------\n // Public methods\n // -------------------------------------------------------------------------\n\n /**\n * Submit a video URL for transcription. Costs 1 credit.\n *\n * If the video was already transcribed, returns a `DuplicateResult` instead.\n *\n * @see https://www.reelscribe.app/api — POST /v1/transcribe\n */\n async transcribe(options: TranscribeOptions): Promise<TranscribeResult | DuplicateResult> {\n return this.request('POST', 'transcribe', options)\n }\n\n /**\n * Fetch a single transcription by Convex document ID or requestId.\n *\n * @see https://www.reelscribe.app/api — GET /v1/transcriptions?id=...\n */\n async getTranscription(options: GetTranscriptionOptions): Promise<Transcription> {\n const params = new URLSearchParams()\n if (options.id) params.set('id', options.id)\n if (options.requestId) params.set('requestId', options.requestId)\n return this.request('GET', `transcriptions?${params}`)\n }\n\n /**\n * List all your transcriptions, optionally filtered by status.\n *\n * @see https://www.reelscribe.app/api — GET /v1/transcriptions\n */\n async listTranscriptions(options?: ListTranscriptionsOptions): Promise<TranscriptionList> {\n const params = new URLSearchParams()\n if (options?.status) params.set('status', options.status)\n const qs = params.toString()\n return this.request('GET', `transcriptions${qs ? `?${qs}` : ''}`)\n }\n\n /**\n * Check your credit balance, subscription tier, and storage usage.\n *\n * @see https://www.reelscribe.app/api — GET /v1/credits\n */\n async getCredits(): Promise<Credits> {\n return this.request('GET', 'credits')\n }\n\n /**\n * Get your current settings.\n *\n * @see https://www.reelscribe.app/api — GET /v1/settings\n */\n async getSettings(): Promise<Settings> {\n return this.request('GET', 'settings')\n }\n\n /**\n * Update your settings (e.g. auto-prune storage).\n *\n * @see https://www.reelscribe.app/api — PATCH /v1/settings\n */\n async updateSettings(options: UpdateSettingsOptions): Promise<Settings> {\n return this.request('PATCH', 'settings', options)\n }\n\n /**\n * Check whether the API is healthy. Does not require authentication.\n *\n * @see https://www.reelscribe.app/api — GET /v1/health\n */\n async health(): Promise<HealthCheck> {\n const res = await this._fetch(`${this.baseUrl}/v1/health`)\n return res.json()\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACKO,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAMzC,YAAY,MAAoB;AAC9B,UAAM,KAAK,OAAO;AAClB,SAAK,OAAO;AACZ,SAAK,OAAO,KAAK;AACjB,SAAK,SAAS,KAAK;AAAA,EACrB;AACF;;;ACDA,IAAM,mBAAmB;AAclB,IAAM,aAAN,MAAiB;AAAA,EAKtB,YAAY,QAAgB,SAA6B;AACvD,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,mEAAmE;AAChG,SAAK,SAAS;AACd,SAAK,WAAW,SAAS,WAAW,kBAAkB,QAAQ,QAAQ,EAAE;AACxE,SAAK,SAAS,SAAS,SAAS,WAAW;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,QAAW,QAAgB,MAAc,MAA4B;AACjF,UAAM,MAAM,GAAG,KAAK,OAAO,OAAO,IAAI;AACtC,UAAM,UAAkC;AAAA,MACtC,eAAe,UAAU,KAAK,MAAM;AAAA,MACpC,gBAAgB;AAAA,IAClB;AAEA,UAAM,MAAM,MAAM,KAAK,OAAO,KAAK;AAAA,MACjC;AAAA,MACA;AAAA,MACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,IACtC,CAAC;AAED,UAAM,OAAO,MAAM,IAAI,KAAK;AAE5B,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,IAAI,gBAAgB,KAAK,SAAS,EAAE,MAAM,WAAW,SAAS,IAAI,YAAY,QAAQ,IAAI,OAAO,CAAC;AAAA,IAC1G;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,WAAW,SAAyE;AACxF,WAAO,KAAK,QAAQ,QAAQ,cAAc,OAAO;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,iBAAiB,SAA0D;AAC/E,UAAM,SAAS,IAAI,gBAAgB;AACnC,QAAI,QAAQ,GAAI,QAAO,IAAI,MAAM,QAAQ,EAAE;AAC3C,QAAI,QAAQ,UAAW,QAAO,IAAI,aAAa,QAAQ,SAAS;AAChE,WAAO,KAAK,QAAQ,OAAO,kBAAkB,MAAM,EAAE;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,mBAAmB,SAAiE;AACxF,UAAM,SAAS,IAAI,gBAAgB;AACnC,QAAI,SAAS,OAAQ,QAAO,IAAI,UAAU,QAAQ,MAAM;AACxD,UAAM,KAAK,OAAO,SAAS;AAC3B,WAAO,KAAK,QAAQ,OAAO,iBAAiB,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aAA+B;AACnC,WAAO,KAAK,QAAQ,OAAO,SAAS;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,cAAiC;AACrC,WAAO,KAAK,QAAQ,OAAO,UAAU;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,eAAe,SAAmD;AACtE,WAAO,KAAK,QAAQ,SAAS,YAAY,OAAO;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,SAA+B;AACnC,UAAM,MAAM,MAAM,KAAK,OAAO,GAAG,KAAK,OAAO,YAAY;AACzD,WAAO,IAAI,KAAK;AAAA,EAClB;AACF;","names":[]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var ReelScribeError = class extends Error {
|
|
3
|
+
constructor(body) {
|
|
4
|
+
super(body.message);
|
|
5
|
+
this.name = "ReelScribeError";
|
|
6
|
+
this.code = body.code;
|
|
7
|
+
this.status = body.status;
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// src/client.ts
|
|
12
|
+
var DEFAULT_BASE_URL = "https://www.reelscribe.app";
|
|
13
|
+
var ReelScribe = class {
|
|
14
|
+
constructor(apiKey, options) {
|
|
15
|
+
if (!apiKey) throw new Error("An API key is required. Get one at https://www.reelscribe.app/api");
|
|
16
|
+
this.apiKey = apiKey;
|
|
17
|
+
this.baseUrl = (options?.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
18
|
+
this._fetch = options?.fetch ?? globalThis.fetch;
|
|
19
|
+
}
|
|
20
|
+
// -------------------------------------------------------------------------
|
|
21
|
+
// Internal helpers
|
|
22
|
+
// -------------------------------------------------------------------------
|
|
23
|
+
async request(method, path, body) {
|
|
24
|
+
const url = `${this.baseUrl}/v1/${path}`;
|
|
25
|
+
const headers = {
|
|
26
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
27
|
+
"Content-Type": "application/json"
|
|
28
|
+
};
|
|
29
|
+
const res = await this._fetch(url, {
|
|
30
|
+
method,
|
|
31
|
+
headers,
|
|
32
|
+
body: body ? JSON.stringify(body) : void 0
|
|
33
|
+
});
|
|
34
|
+
const json = await res.json();
|
|
35
|
+
if (!res.ok) {
|
|
36
|
+
throw new ReelScribeError(json.error ?? { code: "UNKNOWN", message: res.statusText, status: res.status });
|
|
37
|
+
}
|
|
38
|
+
return json;
|
|
39
|
+
}
|
|
40
|
+
// -------------------------------------------------------------------------
|
|
41
|
+
// Public methods
|
|
42
|
+
// -------------------------------------------------------------------------
|
|
43
|
+
/**
|
|
44
|
+
* Submit a video URL for transcription. Costs 1 credit.
|
|
45
|
+
*
|
|
46
|
+
* If the video was already transcribed, returns a `DuplicateResult` instead.
|
|
47
|
+
*
|
|
48
|
+
* @see https://www.reelscribe.app/api — POST /v1/transcribe
|
|
49
|
+
*/
|
|
50
|
+
async transcribe(options) {
|
|
51
|
+
return this.request("POST", "transcribe", options);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Fetch a single transcription by Convex document ID or requestId.
|
|
55
|
+
*
|
|
56
|
+
* @see https://www.reelscribe.app/api — GET /v1/transcriptions?id=...
|
|
57
|
+
*/
|
|
58
|
+
async getTranscription(options) {
|
|
59
|
+
const params = new URLSearchParams();
|
|
60
|
+
if (options.id) params.set("id", options.id);
|
|
61
|
+
if (options.requestId) params.set("requestId", options.requestId);
|
|
62
|
+
return this.request("GET", `transcriptions?${params}`);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* List all your transcriptions, optionally filtered by status.
|
|
66
|
+
*
|
|
67
|
+
* @see https://www.reelscribe.app/api — GET /v1/transcriptions
|
|
68
|
+
*/
|
|
69
|
+
async listTranscriptions(options) {
|
|
70
|
+
const params = new URLSearchParams();
|
|
71
|
+
if (options?.status) params.set("status", options.status);
|
|
72
|
+
const qs = params.toString();
|
|
73
|
+
return this.request("GET", `transcriptions${qs ? `?${qs}` : ""}`);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Check your credit balance, subscription tier, and storage usage.
|
|
77
|
+
*
|
|
78
|
+
* @see https://www.reelscribe.app/api — GET /v1/credits
|
|
79
|
+
*/
|
|
80
|
+
async getCredits() {
|
|
81
|
+
return this.request("GET", "credits");
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get your current settings.
|
|
85
|
+
*
|
|
86
|
+
* @see https://www.reelscribe.app/api — GET /v1/settings
|
|
87
|
+
*/
|
|
88
|
+
async getSettings() {
|
|
89
|
+
return this.request("GET", "settings");
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Update your settings (e.g. auto-prune storage).
|
|
93
|
+
*
|
|
94
|
+
* @see https://www.reelscribe.app/api — PATCH /v1/settings
|
|
95
|
+
*/
|
|
96
|
+
async updateSettings(options) {
|
|
97
|
+
return this.request("PATCH", "settings", options);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Check whether the API is healthy. Does not require authentication.
|
|
101
|
+
*
|
|
102
|
+
* @see https://www.reelscribe.app/api — GET /v1/health
|
|
103
|
+
*/
|
|
104
|
+
async health() {
|
|
105
|
+
const res = await this._fetch(`${this.baseUrl}/v1/health`);
|
|
106
|
+
return res.json();
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
export {
|
|
110
|
+
ReelScribe,
|
|
111
|
+
ReelScribeError
|
|
112
|
+
};
|
|
113
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/client.ts"],"sourcesContent":["import type { ApiErrorBody } from './types'\n\n/**\n * Error thrown when the ReelScribe API returns a non-2xx response.\n */\nexport class ReelScribeError extends Error {\n /** Machine-readable error code (e.g. `INSUFFICIENT_CREDITS`). */\n readonly code: string\n /** HTTP status code. */\n readonly status: number\n\n constructor(body: ApiErrorBody) {\n super(body.message)\n this.name = 'ReelScribeError'\n this.code = body.code\n this.status = body.status\n }\n}\n","import { ReelScribeError } from './errors'\nimport type {\n Credits,\n DuplicateResult,\n GetTranscriptionOptions,\n HealthCheck,\n ListTranscriptionsOptions,\n ReelScribeOptions,\n Settings,\n TranscribeOptions,\n TranscribeResult,\n Transcription,\n TranscriptionList,\n UpdateSettingsOptions,\n} from './types'\n\nconst DEFAULT_BASE_URL = 'https://www.reelscribe.app'\n\n/**\n * ReelScribe API client.\n *\n * @example\n * ```ts\n * const rs = new ReelScribe('rs_your_api_key')\n * const { requestId } = await rs.transcribe({ url: 'https://www.instagram.com/reel/ABC123/' })\n * const result = await rs.getTranscription({ requestId })\n * ```\n *\n * @see https://www.reelscribe.app/api — full API documentation\n */\nexport class ReelScribe {\n private readonly apiKey: string\n private readonly baseUrl: string\n private readonly _fetch: typeof globalThis.fetch\n\n constructor(apiKey: string, options?: ReelScribeOptions) {\n if (!apiKey) throw new Error('An API key is required. Get one at https://www.reelscribe.app/api')\n this.apiKey = apiKey\n this.baseUrl = (options?.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '')\n this._fetch = options?.fetch ?? globalThis.fetch\n }\n\n // -------------------------------------------------------------------------\n // Internal helpers\n // -------------------------------------------------------------------------\n\n private async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}/v1/${path}`\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n }\n\n const res = await this._fetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n })\n\n const json = await res.json()\n\n if (!res.ok) {\n throw new ReelScribeError(json.error ?? { code: 'UNKNOWN', message: res.statusText, status: res.status })\n }\n\n return json as T\n }\n\n // -------------------------------------------------------------------------\n // Public methods\n // -------------------------------------------------------------------------\n\n /**\n * Submit a video URL for transcription. Costs 1 credit.\n *\n * If the video was already transcribed, returns a `DuplicateResult` instead.\n *\n * @see https://www.reelscribe.app/api — POST /v1/transcribe\n */\n async transcribe(options: TranscribeOptions): Promise<TranscribeResult | DuplicateResult> {\n return this.request('POST', 'transcribe', options)\n }\n\n /**\n * Fetch a single transcription by Convex document ID or requestId.\n *\n * @see https://www.reelscribe.app/api — GET /v1/transcriptions?id=...\n */\n async getTranscription(options: GetTranscriptionOptions): Promise<Transcription> {\n const params = new URLSearchParams()\n if (options.id) params.set('id', options.id)\n if (options.requestId) params.set('requestId', options.requestId)\n return this.request('GET', `transcriptions?${params}`)\n }\n\n /**\n * List all your transcriptions, optionally filtered by status.\n *\n * @see https://www.reelscribe.app/api — GET /v1/transcriptions\n */\n async listTranscriptions(options?: ListTranscriptionsOptions): Promise<TranscriptionList> {\n const params = new URLSearchParams()\n if (options?.status) params.set('status', options.status)\n const qs = params.toString()\n return this.request('GET', `transcriptions${qs ? `?${qs}` : ''}`)\n }\n\n /**\n * Check your credit balance, subscription tier, and storage usage.\n *\n * @see https://www.reelscribe.app/api — GET /v1/credits\n */\n async getCredits(): Promise<Credits> {\n return this.request('GET', 'credits')\n }\n\n /**\n * Get your current settings.\n *\n * @see https://www.reelscribe.app/api — GET /v1/settings\n */\n async getSettings(): Promise<Settings> {\n return this.request('GET', 'settings')\n }\n\n /**\n * Update your settings (e.g. auto-prune storage).\n *\n * @see https://www.reelscribe.app/api — PATCH /v1/settings\n */\n async updateSettings(options: UpdateSettingsOptions): Promise<Settings> {\n return this.request('PATCH', 'settings', options)\n }\n\n /**\n * Check whether the API is healthy. Does not require authentication.\n *\n * @see https://www.reelscribe.app/api — GET /v1/health\n */\n async health(): Promise<HealthCheck> {\n const res = await this._fetch(`${this.baseUrl}/v1/health`)\n return res.json()\n }\n}\n"],"mappings":";AAKO,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAMzC,YAAY,MAAoB;AAC9B,UAAM,KAAK,OAAO;AAClB,SAAK,OAAO;AACZ,SAAK,OAAO,KAAK;AACjB,SAAK,SAAS,KAAK;AAAA,EACrB;AACF;;;ACDA,IAAM,mBAAmB;AAclB,IAAM,aAAN,MAAiB;AAAA,EAKtB,YAAY,QAAgB,SAA6B;AACvD,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,mEAAmE;AAChG,SAAK,SAAS;AACd,SAAK,WAAW,SAAS,WAAW,kBAAkB,QAAQ,QAAQ,EAAE;AACxE,SAAK,SAAS,SAAS,SAAS,WAAW;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,QAAW,QAAgB,MAAc,MAA4B;AACjF,UAAM,MAAM,GAAG,KAAK,OAAO,OAAO,IAAI;AACtC,UAAM,UAAkC;AAAA,MACtC,eAAe,UAAU,KAAK,MAAM;AAAA,MACpC,gBAAgB;AAAA,IAClB;AAEA,UAAM,MAAM,MAAM,KAAK,OAAO,KAAK;AAAA,MACjC;AAAA,MACA;AAAA,MACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,IACtC,CAAC;AAED,UAAM,OAAO,MAAM,IAAI,KAAK;AAE5B,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,IAAI,gBAAgB,KAAK,SAAS,EAAE,MAAM,WAAW,SAAS,IAAI,YAAY,QAAQ,IAAI,OAAO,CAAC;AAAA,IAC1G;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,WAAW,SAAyE;AACxF,WAAO,KAAK,QAAQ,QAAQ,cAAc,OAAO;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,iBAAiB,SAA0D;AAC/E,UAAM,SAAS,IAAI,gBAAgB;AACnC,QAAI,QAAQ,GAAI,QAAO,IAAI,MAAM,QAAQ,EAAE;AAC3C,QAAI,QAAQ,UAAW,QAAO,IAAI,aAAa,QAAQ,SAAS;AAChE,WAAO,KAAK,QAAQ,OAAO,kBAAkB,MAAM,EAAE;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,mBAAmB,SAAiE;AACxF,UAAM,SAAS,IAAI,gBAAgB;AACnC,QAAI,SAAS,OAAQ,QAAO,IAAI,UAAU,QAAQ,MAAM;AACxD,UAAM,KAAK,OAAO,SAAS;AAC3B,WAAO,KAAK,QAAQ,OAAO,iBAAiB,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aAA+B;AACnC,WAAO,KAAK,QAAQ,OAAO,SAAS;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,cAAiC;AACrC,WAAO,KAAK,QAAQ,OAAO,UAAU;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,eAAe,SAAmD;AACtE,WAAO,KAAK,QAAQ,SAAS,YAAY,OAAO;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,SAA+B;AACnC,UAAM,MAAM,MAAM,KAAK,OAAO,GAAG,KAAK,OAAO,YAAY;AACzD,WAAO,IAAI,KAAK;AAAA,EAClB;AACF;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "reelscribe",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Official Node.js/TypeScript SDK for the ReelScribe API — transcribe Instagram Reels, TikTok videos, and YouTube shorts programmatically.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup",
|
|
20
|
+
"prepublishOnly": "npm run build"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"reelscribe",
|
|
24
|
+
"transcription",
|
|
25
|
+
"instagram",
|
|
26
|
+
"tiktok",
|
|
27
|
+
"youtube",
|
|
28
|
+
"reels",
|
|
29
|
+
"shorts",
|
|
30
|
+
"video",
|
|
31
|
+
"api",
|
|
32
|
+
"sdk",
|
|
33
|
+
"speech-to-text"
|
|
34
|
+
],
|
|
35
|
+
"author": "ReelScribe <support@reelscribe.app>",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"homepage": "https://www.reelscribe.app",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "https://github.com/rara-cyber/reelscribe-js.git"
|
|
41
|
+
},
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/rara-cyber/reelscribe-js/issues"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=18.0.0"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"tsup": "^8.0.0",
|
|
50
|
+
"typescript": "^5.4.0"
|
|
51
|
+
}
|
|
52
|
+
}
|