swadhinbiswas

[email protected]
2026-03-14 19:15:24 +0600 committed NaN years ago
4e7604c
commit 4e7604c
1 file changed
+621 -0
Showing 1 changed file+621-0
β–Όdocs/15-api-reference.md
+621-0
1
+# πŸ”Œ API Reference
2
+
3
+Complete API documentation for OpenGrammar backend.
4
+
5
+---
6
+
7
+## πŸ“‹ Overview
8
+
9
+OpenGrammar provides a RESTful API for grammar checking, tone rewriting, and writing analysis.
10
+
11
+**Base URL:** `http://localhost:8787` (local) or your deployed URL
12
+
13
+**Content Type:** `application/json`
14
+
15
+---
16
+
17
+## πŸ”‘ Authentication
18
+
19
+Most endpoints don't require authentication for basic usage. However, AI-powered features require API keys configured in environment variables or passed in requests.
20
+
21
+---
22
+
23
+## πŸ“€ Endpoints
24
+
25
+### Health Check
26
+
27
+#### `GET /health`
28
+
29
+Check server health and status.
30
+
31
+**Request:**
32
+```bash
33
+curl http://localhost:8787/health
34
+```
35
+
36
+**Response (200 OK):**
37
+```json
38
+{
39
+ "status": "healthy",
40
+ "timestamp": "2026-03-14T12:00:00.000Z",
41
+ "environment": "production",
42
+ "version": "2.1.0"
43
+}
44
+```
45
+
46
+**Response Fields:**
47
+| Field | Type | Description |
48
+|-------|------|-------------|
49
+| `status` | string | Server status (`healthy`, `unhealthy`) |
50
+| `timestamp` | string | ISO 8601 timestamp |
51
+| `environment` | string | Environment name |
52
+| `version` | string | API version |
53
+
54
+---
55
+
56
+### List Providers
57
+
58
+#### `GET /providers`
59
+
60
+Get list of available AI providers.
61
+
62
+**Request:**
63
+```bash
64
+curl http://localhost:8787/providers
65
+```
66
+
67
+**Response (200 OK):**
68
+```json
69
+{
70
+ "providers": [
71
+ {
72
+ "id": "groq",
73
+ "name": "Groq",
74
+ "description": "Fast inference with free tier",
75
+ "models": ["llama-3.1-70b-versatile", "llama-3.1-8b-instant"],
76
+ "requiresApiKey": true,
77
+ "defaultModel": "llama-3.1-70b-versatile"
78
+ },
79
+ {
80
+ "id": "openai",
81
+ "name": "OpenAI",
82
+ "description": "Best quality grammar checking",
83
+ "models": ["gpt-4o-mini", "gpt-4o", "gpt-3.5-turbo"],
84
+ "requiresApiKey": true,
85
+ "defaultModel": "gpt-4o-mini"
86
+ },
87
+ {
88
+ "id": "ollama",
89
+ "name": "Ollama (Local)",
90
+ "description": "Run models locally",
91
+ "models": ["qwen2.5:1.5b", "phi4-mini:3.8b"],
92
+ "requiresApiKey": false,
93
+ "defaultModel": "qwen2.5:1.5b"
94
+ }
95
+ ]
96
+}
97
+```
98
+
99
+---
100
+
101
+### List Models
102
+
103
+#### `POST /models`
104
+
105
+Get available models for a specific provider.
106
+
107
+**Request:**
108
+```bash
109
+curl -X POST http://localhost:8787/models \
110
+ -H "Content-Type: application/json" \
111
+ -d '{
112
+ "provider": "groq"
113
+ }'
114
+```
115
+
116
+**Response (200 OK):**
117
+```json
118
+{
119
+ "provider": "groq",
120
+ "models": [
121
+ {
122
+ "id": "llama-3.1-70b-versatile",
123
+ "name": "Llama 3.1 70B",
124
+ "description": "Best for grammar checking",
125
+ "contextWindow": 128000,
126
+ "speed": "fast",
127
+ "quality": "excellent"
128
+ },
129
+ {
130
+ "id": "llama-3.1-8b-instant",
131
+ "name": "Llama 3.1 8B",
132
+ "description": "Fast inference",
133
+ "contextWindow": 128000,
134
+ "speed": "very fast",
135
+ "quality": "good"
136
+ }
137
+ ]
138
+}
139
+```
140
+
141
+---
142
+
143
+### Analyze Text
144
+
145
+#### `POST /analyze`
146
+
147
+Analyze text for grammar, spelling, and style issues.
148
+
149
+**Request:**
150
+```bash
151
+curl -X POST http://localhost:8787/analyze \
152
+ -H "Content-Type: application/json" \
153
+ -d '{
154
+ "text": "me and him went to the store and buyed milks",
155
+ "provider": "groq",
156
+ "model": "llama-3.1-70b-versatile",
157
+ "apiKey": "gsk_xxx",
158
+ "options": {
159
+ "checkGrammar": true,
160
+ "checkSpelling": true,
161
+ "checkStyle": true,
162
+ "checkClarity": true
163
+ }
164
+ }'
165
+```
166
+
167
+**Request Fields:**
168
+| Field | Type | Required | Description |
169
+|-------|------|----------|-------------|
170
+| `text` | string | Yes | Text to analyze (max 50,000 chars) |
171
+| `provider` | string | No | AI provider (default: rule-based only) |
172
+| `model` | string | No | Model to use |
173
+| `apiKey` | string | No | API key (if not set in env) |
174
+| `options` | object | No | Analysis options |
175
+
176
+**Response (200 OK):**
177
+```json
178
+{
179
+ "issues": [
180
+ {
181
+ "type": "grammar",
182
+ "severity": "error",
183
+ "original": "me and him",
184
+ "suggestion": "he and I",
185
+ "reason": "Subject pronoun error. Use subject pronouns for the subject of a sentence.",
186
+ "offset": 0,
187
+ "length": 9,
188
+ "category": "grammar"
189
+ },
190
+ {
191
+ "type": "spelling",
192
+ "severity": "error",
193
+ "original": "buyed",
194
+ "suggestion": "bought",
195
+ "reason": "Irregular verb form. The past tense of 'buy' is 'bought'.",
196
+ "offset": 38,
197
+ "length": 5,
198
+ "category": "spelling"
199
+ }
200
+ ],
201
+ "metadata": {
202
+ "textLength": 49,
203
+ "issuesCount": 2,
204
+ "processingTimeMs": 245,
205
+ "provider": "groq",
206
+ "model": "llama-3.1-70b-versatile",
207
+ "ruleBasedCount": 0,
208
+ "aiBasedCount": 2
209
+ }
210
+}
211
+```
212
+
213
+**Response Fields:**
214
+| Field | Type | Description |
215
+|-------|------|-------------|
216
+| `issues` | array | List of detected issues |
217
+| `metadata` | object | Analysis metadata |
218
+
219
+**Issue Object:**
220
+| Field | Type | Description |
221
+|-------|------|-------------|
222
+| `type` | string | Issue type (`grammar`, `spelling`, `style`, `clarity`) |
223
+| `severity` | string | Severity (`error`, `warning`, `suggestion`) |
224
+| `original` | string | Original text |
225
+| `suggestion` | string | Suggested replacement |
226
+| `reason` | string | Explanation |
227
+| `offset` | number | Character offset in text |
228
+| `length` | number | Length of issue |
229
+| `category` | string | Category for grouping |
230
+
231
+**Error Responses:**
232
+
233
+**400 Bad Request:**
234
+```json
235
+{
236
+ "error": "Text too long",
237
+ "message": "Maximum text length is 50,000 characters"
238
+}
239
+```
240
+
241
+**401 Unauthorized:**
242
+```json
243
+{
244
+ "error": "API key required",
245
+ "message": "Please provide an API key for this provider"
246
+}
247
+```
248
+
249
+**500 Internal Server Error:**
250
+```json
251
+{
252
+ "error": "Provider error",
253
+ "message": "Failed to connect to AI provider"
254
+}
255
+```
256
+
257
+---
258
+
259
+### Rewrite Text
260
+
261
+#### `POST /rewrite`
262
+
263
+Rewrite text in a specific tone or style.
264
+
265
+**Request:**
266
+```bash
267
+curl -X POST http://localhost:8787/rewrite \
268
+ -H "Content-Type: application/json" \
269
+ -d '{
270
+ "text": "hey whats up can we talk",
271
+ "tone": "formal",
272
+ "provider": "groq",
273
+ "model": "llama-3.1-70b-versatile",
274
+ "apiKey": "gsk_xxx"
275
+ }'
276
+```
277
+
278
+**Request Fields:**
279
+| Field | Type | Required | Description |
280
+|-------|------|----------|-------------|
281
+| `text` | string | Yes | Text to rewrite |
282
+| `tone` | string | Yes | Target tone |
283
+| `provider` | string | No | AI provider |
284
+| `model` | string | No | Model to use |
285
+| `apiKey` | string | No | API key |
286
+
287
+**Available Tones:**
288
+- `formal` - Professional, academic
289
+- `casual` - Relaxed, informal
290
+- `professional` - Business appropriate
291
+- `friendly` - Warm, approachable
292
+- `concise` - Brief, to the point
293
+- `detailed` - Comprehensive, thorough
294
+- `persuasive` - Convincing, compelling
295
+- `neutral` - Balanced, unbiased
296
+
297
+**Response (200 OK):**
298
+```json
299
+{
300
+ "original": "hey whats up can we talk",
301
+ "rewritten": "Hello, how are you? May we have a conversation?",
302
+ "tone": "formal",
303
+ "provider": "groq",
304
+ "model": "llama-3.1-70b-versatile",
305
+ "metadata": {
306
+ "originalLength": 26,
307
+ "rewrittenLength": 49,
308
+ "processingTimeMs": 1250,
309
+ "confidenceScore": 0.95
310
+ }
311
+}
312
+```
313
+
314
+**Response Fields:**
315
+| Field | Type | Description |
316
+|-------|------|-------------|
317
+| `original` | string | Original text |
318
+| `rewritten` | string | Rewritten text |
319
+| `tone` | string | Applied tone |
320
+| `provider` | string | AI provider used |
321
+| `model` | string | Model used |
322
+| `metadata` | object | Additional information |
323
+
324
+---
325
+
326
+### Get Statistics
327
+
328
+#### `POST /statistics`
329
+
330
+Get detailed writing statistics.
331
+
332
+**Request:**
333
+```bash
334
+curl -X POST http://localhost:8787/statistics \
335
+ -H "Content-Type: application/json" \
336
+ -d '{
337
+ "text": "Your complete text here..."
338
+ }'
339
+```
340
+
341
+**Response (200 OK):**
342
+```json
343
+{
344
+ "basic": {
345
+ "words": 1248,
346
+ "characters": 6542,
347
+ "charactersNoSpaces": 5421,
348
+ "sentences": 87,
349
+ "paragraphs": 12,
350
+ "syllables": 1876
351
+ },
352
+ "readability": {
353
+ "fleschReadingEase": 78.5,
354
+ "fleschKincaidGrade": 8.5,
355
+ "automatedReadabilityIndex": 9.2,
356
+ "readingLevel": "Excellent"
357
+ },
358
+ "time": {
359
+ "readingTimeSeconds": 374,
360
+ "readingTimeFormatted": "6 min 14 sec",
361
+ "speakingTimeSeconds": 499,
362
+ "speakingTimeFormatted": "8 min 19 sec"
363
+ },
364
+ "vocabulary": {
365
+ "uniqueWords": 542,
366
+ "vocabularyDiversity": 43.4,
367
+ "averageWordLength": 4.8,
368
+ "longWords": 156
369
+ },
370
+ "issues": {
371
+ "grammar": 3,
372
+ "spelling": 5,
373
+ "style": 7,
374
+ "clarity": 4,
375
+ "total": 19
376
+ }
377
+}
378
+```
379
+
380
+**Response Fields:**
381
+
382
+**Basic:**
383
+| Field | Type | Description |
384
+|-------|------|-------------|
385
+| `words` | number | Total words |
386
+| `characters` | number | Characters with spaces |
387
+| `charactersNoSpaces` | number | Characters without spaces |
388
+| `sentences` | number | Total sentences |
389
+| `paragraphs` | number | Total paragraphs |
390
+| `syllables` | number | Total syllables |
391
+
392
+**Readability:**
393
+| Field | Type | Description |
394
+|-------|------|-------------|
395
+| `fleschReadingEase` | number | 0-100 score |
396
+| `fleschKincaidGrade` | number | US grade level |
397
+| `automatedReadabilityIndex` | number | ARI score |
398
+| `readingLevel` | string | Text description |
399
+
400
+**Time:**
401
+| Field | Type | Description |
402
+|-------|------|-------------|
403
+| `readingTimeSeconds` | number | Seconds to read |
404
+| `readingTimeFormatted` | string | Human-readable |
405
+| `speakingTimeSeconds` | number | Seconds to speak |
406
+| `speakingTimeFormatted` | string | Human-readable |
407
+
408
+**Vocabulary:**
409
+| Field | Type | Description |
410
+|-------|------|-------------|
411
+| `uniqueWords` | number | Different words |
412
+| `vocabularyDiversity` | number | Percentage |
413
+| `averageWordLength` | number | Mean characters |
414
+| `longWords` | number | Words > 6 chars |
415
+
416
+---
417
+
418
+## πŸ“ Code Examples
419
+
420
+### JavaScript/TypeScript
421
+
422
+```typescript
423
+// Analyze text
424
+async function analyzeText(text: string) {
425
+ const response = await fetch('http://localhost:8787/analyze', {
426
+ method: 'POST',
427
+ headers: { 'Content-Type': 'application/json' },
428
+ body: JSON.stringify({
429
+ text: text,
430
+ provider: 'groq',
431
+ model: 'llama-3.1-70b-versatile'
432
+ })
433
+ });
434
+
435
+ const data = await response.json();
436
+ return data;
437
+}
438
+
439
+// Rewrite text
440
+async function rewriteText(text: string, tone: string) {
441
+ const response = await fetch('http://localhost:8787/rewrite', {
442
+ method: 'POST',
443
+ headers: { 'Content-Type': 'application/json' },
444
+ body: JSON.stringify({
445
+ text: text,
446
+ tone: tone
447
+ })
448
+ });
449
+
450
+ const data = await response.json();
451
+ return data.rewritten;
452
+}
453
+```
454
+
455
+### Python
456
+
457
+```python
458
+import requests
459
+
460
+# Analyze text
461
+def analyze_text(text):
462
+ response = requests.post(
463
+ 'http://localhost:8787/analyze',
464
+ json={
465
+ 'text': text,
466
+ 'provider': 'groq',
467
+ 'model': 'llama-3.1-70b-versatile'
468
+ }
469
+ )
470
+ return response.json()
471
+
472
+# Rewrite text
473
+def rewrite_text(text, tone):
474
+ response = requests.post(
475
+ 'http://localhost:8787/rewrite',
476
+ json={
477
+ 'text': text,
478
+ 'tone': tone
479
+ }
480
+ )
481
+ return response.json()['rewritten']
482
+
483
+# Get statistics
484
+def get_statistics(text):
485
+ response = requests.post(
486
+ 'http://localhost:8787/statistics',
487
+ json={'text': text}
488
+ )
489
+ return response.json()
490
+```
491
+
492
+### cURL
493
+
494
+```bash
495
+# Analyze
496
+curl -X POST http://localhost:8787/analyze \
497
+ -H "Content-Type: application/json" \
498
+ -d '{"text": "me and him went", "provider": "groq"}'
499
+
500
+# Rewrite
501
+curl -X POST http://localhost:8787/rewrite \
502
+ -H "Content-Type: application/json" \
503
+ -d '{"text": "hey", "tone": "formal"}'
504
+
505
+# Statistics
506
+curl -X POST http://localhost:8787/statistics \
507
+ -H "Content-Type: application/json" \
508
+ -d '{"text": "Your text here"}'
509
+```
510
+
511
+---
512
+
513
+## πŸ”§ Error Handling
514
+
515
+### Error Response Format
516
+
517
+```json
518
+{
519
+ "error": "Error type",
520
+ "message": "Detailed error message",
521
+ "code": "ERROR_CODE"
522
+}
523
+```
524
+
525
+### Common Error Codes
526
+
527
+| Code | HTTP Status | Description |
528
+|------|-------------|-------------|
529
+| `INVALID_REQUEST` | 400 | Malformed request |
530
+| `TEXT_TOO_LONG` | 400 | Text exceeds 50,000 chars |
531
+| `API_KEY_REQUIRED` | 401 | API key needed |
532
+| `INVALID_API_KEY` | 401 | API key invalid |
533
+| `PROVIDER_ERROR` | 500 | AI provider error |
534
+| `RATE_LIMITED` | 429 | Too many requests |
535
+| `SERVICE_UNAVAILABLE` | 503 | Service down |
536
+
537
+---
538
+
539
+## πŸ“Š Rate Limiting
540
+
541
+### Default Limits
542
+
543
+| Endpoint | Limit | Window |
544
+|----------|-------|--------|
545
+| `/analyze` | 100 req | 1 minute |
546
+| `/rewrite` | 50 req | 1 minute |
547
+| `/statistics` | 200 req | 1 minute |
548
+| `/health` | Unlimited | - |
549
+
550
+### Rate Limit Response
551
+
552
+**429 Too Many Requests:**
553
+```json
554
+{
555
+ "error": "Rate limit exceeded",
556
+ "message": "Too many requests. Please try again in 30 seconds.",
557
+ "retryAfter": 30
558
+}
559
+```
560
+
561
+---
562
+
563
+## πŸ”’ Security
564
+
565
+### Input Validation
566
+
567
+- Maximum text length: 50,000 characters
568
+- Sanitized input
569
+- Type checking
570
+- JSON validation
571
+
572
+### API Key Handling
573
+
574
+- Keys stored in environment variables
575
+- Never logged
576
+- Passed securely to providers
577
+- Not retained by backend
578
+
579
+### CORS
580
+
581
+Configured for browser extensions:
582
+```typescript
583
+app.use('*', cors({
584
+ origin: ['chrome-extension://*', 'moz-extension://*'],
585
+ credentials: true
586
+}));
587
+```
588
+
589
+---
590
+
591
+## πŸ“ˆ Performance
592
+
593
+### Response Times
594
+
595
+| Endpoint | Avg (ms) | P95 (ms) | P99 (ms) |
596
+|----------|----------|----------|----------|
597
+| `/health` | 10 | 20 | 50 |
598
+| `/analyze` (rule-based) | 50 | 100 | 200 |
599
+| `/analyze` (AI) | 1000 | 2000 | 3000 |
600
+| `/rewrite` | 1500 | 2500 | 4000 |
601
+| `/statistics` | 100 | 200 | 300 |
602
+
603
+### Optimization Tips
604
+
605
+1. **Use rule-based for simple checks** - Faster, no API cost
606
+2. **Batch requests** - Combine multiple texts
607
+3. **Cache results** - Store common analyses
608
+4. **Use appropriate models** - Smaller models for simple tasks
609
+
610
+---
611
+
612
+## πŸ“š Related Documentation
613
+
614
+- [Backend Deployment](05-backend-deployment.md) - Deploy the API
615
+- [AI Providers](07-ai-providers.md) - Configure providers
616
+- [Troubleshooting](18-troubleshooting.md) - Fix issues
617
+
618
+---
619
+
620
+**API Version:** 2.1.0
621
+**Last Updated:** March 2026
0
622