{"_id":"@allroads/client","_rev":"3-34a5126b8c1f1cce3873d3efea3c626d","name":"@allroads/client","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@allroads/client","version":"0.1.0","keywords":["allroads","api","client","video","vehicle","analysis"],"author":{"name":"AllRoads"},"license":"MIT","_id":"@allroads/client@0.1.0","maintainers":[{"name":"zenodflow","email":"zenodflow@gmail.com"}],"homepage":"https://allroads.ai","bugs":{"url":"https://github.com/panoway/allroads-api/issues"},"dist":{"shasum":"0df8c8f112ffff3af9a907ec6a4472328b744515","tarball":"https://registry.npmjs.org/@allroads/client/-/client-0.1.0.tgz","fileCount":8,"integrity":"sha512-xIfl3DCwhOw9fHD2tfNaCaN7Eq12eclcCb6Uh73d0RJRl0hgHdu6h59XCQV2pETz6dlahYFS0fkuhV9nkRcltw==","signatures":[{"sig":"MEQCIGzdeYdltUFmr2fUweqS8lLNzM61R5g/mX893cCnfjV+AiBhVWAEOubKzN2tBasWWjg5RWpltp4N3PU25dFTvpSpBA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":122013},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"7ba81f807ff4d349770f1c46dbf277744e431348","scripts":{"dev":"tsup --watch","build":"tsup","clean":"rm -rf dist","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"zenodflow","email":"zenodflow@gmail.com"},"repository":{"url":"git+https://github.com/panoway/allroads-api.git","type":"git","directory":"api/ts"},"_npmVersion":"11.8.0","description":"TypeScript/JavaScript client for AllRoads API","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.1","typescript":"^5.3.3","@types/node":"^20.11.0"},"_npmOperationalInternal":{"tmp":"tmp/client_0.1.0_1769463165907_0.7216740259653953","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@allroads/client","version":"0.1.1","keywords":["allroads","api","client","video","vehicle","analysis"],"author":{"name":"AllRoads"},"license":"MIT","_id":"@allroads/client@0.1.1","maintainers":[{"name":"zenodflow","email":"zenodflow@gmail.com"}],"homepage":"https://allroads.ai","bugs":{"url":"https://github.com/panoway/allroads-api/issues"},"dist":{"shasum":"489e282fc8450c9b25563657caf5dff6b35b485f","tarball":"https://registry.npmjs.org/@allroads/client/-/client-0.1.1.tgz","fileCount":8,"integrity":"sha512-y1d8oYhdUKTWipMw2DkOxMPqVGfqSU/Qe4n9OLKT1tc+1aPotNexB+cLcCQ7ulxeTLY69YVjthhKwPnBaSr2FQ==","signatures":[{"sig":"MEQCIHMI8uigqL7JKCNjXakU4khR6LC7T6nq3MD5nUXrGtolAiARDjbPi9+OIR/059Rwy0WKYKP2D4W6DwL4FWoWKmdjRA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":179173},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"1c00fc855ff0024ef4cb39f9c64edf9686994104","scripts":{"dev":"tsup --watch","build":"tsup","clean":"rm -rf dist","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"zenodflow","email":"zenodflow@gmail.com"},"repository":{"url":"git+https://github.com/panoway/allroads-api.git","type":"git","directory":"api/ts"},"_npmVersion":"11.8.0","description":"TypeScript/JavaScript client for AllRoads API","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.1","typescript":"^5.3.3","@types/node":"^20.11.0"},"_npmOperationalInternal":{"tmp":"tmp/client_0.1.1_1770680884294_0.8882689811047024","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@allroads/client","version":"0.1.2","description":"TypeScript/JavaScript client for AllRoads API","main":"./dist/index.js","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"scripts":{"build":"tsup","dev":"tsup --watch","typecheck":"tsc --noEmit","clean":"rm -rf dist","prepublishOnly":"npm run build"},"keywords":["allroads","api","client","video","vehicle","analysis"],"author":{"name":"AllRoads"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/panoway/allroads-api.git","directory":"api/ts"},"homepage":"https://allroads.ai","bugs":{"url":"https://github.com/panoway/allroads-api/issues"},"devDependencies":{"@types/node":"^20.11.0","tsup":"^8.0.1","typescript":"^5.3.3"},"engines":{"node":">=18.0.0"},"gitHead":"582b0a856468fe1ace81dfca0b34888f62dae70a","_id":"@allroads/client@0.1.2","_nodeVersion":"22.14.0","_npmVersion":"11.8.0","dist":{"integrity":"sha512-UQG7vnKM9X2CgxAasfAUR+YR1+MwM+943jm4UbM4rFneptztSd0hXk/DUPGpH/daaSDkXjEvKP872gVeM1ubRg==","shasum":"b44b580bbbf528da8fa4887faa795ee67802b5b8","tarball":"https://registry.npmjs.org/@allroads/client/-/client-0.1.2.tgz","fileCount":8,"unpackedSize":181997,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIBcM3Y1DVRTjcCzZGiWqQYPw+ZVVAhsIF6U5JCJJ9HssAiAuhaFIBT5NcLlA+0VWttYQ/GH6SUh2P1hVa7Lj6IGbiw=="}]},"_npmUser":{"name":"zenodflow","email":"zenodflow@gmail.com"},"directories":{},"maintainers":[{"name":"zenodflow","email":"zenodflow@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/client_0.1.2_1771867200304_0.8104856634245927"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-26T21:32:45.845Z","modified":"2026-02-23T17:20:00.572Z","0.1.0":"2026-01-26T21:32:46.055Z","0.1.1":"2026-02-09T23:48:04.449Z","0.1.2":"2026-02-23T17:20:00.459Z"},"bugs":{"url":"https://github.com/panoway/allroads-api/issues"},"author":{"name":"AllRoads"},"license":"MIT","homepage":"https://allroads.ai","keywords":["allroads","api","client","video","vehicle","analysis"],"repository":{"type":"git","url":"git+https://github.com/panoway/allroads-api.git","directory":"api/ts"},"description":"TypeScript/JavaScript client for AllRoads API","maintainers":[{"name":"zenodflow","email":"zenodflow@gmail.com"}],"readme":"# @allroads/client\n\nTypeScript/JavaScript client for the AllRoads video analysis platform API.\n\n## Installation\n\n```bash\nnpm install @allroads/client\n# or\nyarn add @allroads/client\n# or\npnpm add @allroads/client\n```\n\n## Quick Start\n\n```typescript\nimport { AllRoadsClient } from '@allroads/client';\n\nconst client = new AllRoadsClient({\n  baseUrl: 'https://xxx.execute-api.us-west-2.amazonaws.com/Prod',\n  apiKey: 'your-api-key'\n});\n\n// Index a video segment\nconst result = await client.indexVideoSegment({\n  segment_seq: 0,\n  init_mp4_url: 'https://example.com/init.mp4',\n  segment_mp4_url: 'https://example.com/segment_0.m4s'\n});\n\nconsole.log('Video ID:', result.video_id);\n```\n\n## Usage\n\n### Video Processing\n\n#### Index Video Segment\n\nMain entry point for video processing. Triggers the complete pipeline: video indexing → scene creation → track creation → VIN resolution.\n\n```typescript\n// Using URLs\nconst result = await client.indexVideoSegment({\n  segment_seq: 0,\n  init_mp4_url: 'https://example.com/init.mp4',\n  segment_mp4_url: 'https://example.com/segment_0.m4s',\n  target_frame_rate: 10.0,\n  detection_batch_size: 4,\n  tracking_chunk_size: 40,\n  eos: false\n});\n\n// Using S3 keys\nconst result = await client.indexVideoSegment({\n  video_id: 'existing-video-id', // Required for segment_seq > 0\n  segment_seq: 1,\n  init_mp4_s3_key: 'videos/init.mp4',\n  segment_mp4_s3_key: 'videos/segment_1.m4s',\n  eos: true // Mark end of stream\n});\n```\n\n#### Crop Index Results\n\nCrop existing analysis results to a specific time range.\n\n```typescript\nconst cropped = await client.cropIndexResults({\n  video_id: 'video-id',\n  start_time: 10.5,\n  end_time: 30.0\n});\n\nconsole.log('Cropped tracks:', cropped.cropped_tracking_results_s3_key);\n```\n\n#### Segment Video\n\nSegment a video into HLS format with fMP4 segments.\n\n```typescript\nconst segments = await client.segmentVideo({\n  clip_s3_key: 'path/to/video.mp4',\n  segments_s3_prefix: 'path/to/segments/',\n  segment_duration: 5.0\n});\n\nconsole.log('Init:', segments.init_filename);\nconsole.log('Segments:', segments.seg_filenames);\n```\n\n#### Start Video Redaction\n\nStart the video redaction pipeline.\n\n```typescript\nconst execution = await client.startVideoRedaction({\n  video_id: 'video-id',\n  track_id: 'track-id',  // optional\n  redaction_width: 1920,  // optional\n  redaction_height: 1080, // optional\n  redaction_type: 'gaussian' // optional\n});\n\nconsole.log('Execution ARN:', execution.executionArn);\n```\n\n#### Query Video Indexing\n\nQuery the indexing status and results of a video. This endpoint is meant to supplement webhooks as a fallback mechanism for state synchronization and reconciliation. Use webhooks for real-time notifications, and this endpoint to query current state when needed.\n\n```typescript\nconst status = await client.queryVideoIndexing({\n  video_id: \"video-id\"\n});\n\nif (status.index_status === \"indexed\") {\n  console.log('Video indexed at:', status.index_result?.indexed_at);\n  console.log('FPS:', status.index_result?.fps);\n  console.log('Duration:', status.index_result?.duration);\n  console.log('Segments:', status.index_result?.num_segments);\n} else if (status.index_status === \"pending\") {\n  console.log('Indexing in progress...');\n  if (status.index_progress) {\n    console.log('Latest aggregation seq:', status.index_progress.latest_aggregation_seq);\n    console.log('Num indexed segments:', status.index_progress.num_indexed_segments);\n    console.log('Watermark completed:', status.index_progress.watermark_completed);\n    console.log('Dedup completed:', status.index_progress.dedup_completed);\n    console.log('Audio completed:', status.index_progress.audio_completed);\n  }\n} else if (status.index_status === \"error\") {\n  console.log('Video indexing failed');\n}\n```\n\n#### Authorize Track Video Playback\n\nGenerate CloudFront signed cookies for secure playback of redacted track videos.\n\n```typescript\nconst auth = await client.authorizeTrackVideoPlayback({\n  track_id: 'track-id',\n  ttl_seconds: 3600 // optional, default: 3600\n});\n\nconsole.log('Playback URL:', auth.playback.url);\nconsole.log('Expires at:', new Date(auth.expires_epoch * 1000));\n\n// Set cookies in your HTTP client/browser to access the HLS stream\n// CloudFront-Policy: auth.cloudfront_signed_cookies['CloudFront-Policy']\n// CloudFront-Signature: auth.cloudfront_signed_cookies['CloudFront-Signature']\n// CloudFront-Key-Pair-Id: auth.cloudfront_signed_cookies['CloudFront-Key-Pair-Id']\n```\n\n### Webhook Management\n\n#### Create Webhook\n\n```typescript\nconst webhook = await client.createWebhook('https://example.com/webhook');\n\nconsole.log('Webhook ID:', webhook.webhook.webhook_id);\nconsole.log('Shared Secret:', webhook.webhook.webhook_shared_secret);\n// Store the shared secret securely - you'll need it to verify webhook signatures\n```\n\n#### Delete Webhook\n\n```typescript\nconst result = await client.deleteWebhook();\nconsole.log('Deleted:', result.webhook?.deleted);\n```\n\n### Vehicle Queries\n\n#### Populate Vehicle Query Table\n\nPopulate the DynamoDB table with vehicle tracking data for efficient querying. This must be called before querying vehicle information.\n\n```typescript\nconst result = await client.populateVehicleQueryTable({\n  video_id: 'video-id'\n});\n\nconsole.log('Message:', result.message);\nconsole.log('Video ID:', result.video_id);\nconsole.log('Number of tracks:', result.num_tracks);\nconsole.log('Number of frames:', result.num_frames);\n```\n\n#### Query Vehicle Info\n\nQuery vehicle information at a specific timestamp and coordinate. Requires the vehicle query table to be populated first (see `populateVehicleQueryTable`).\n\n```typescript\nconst result = await client.queryVehicleInfo({\n  video_id: 'video-id',\n  timestamp: 15.5, // seconds\n  coordinate: [500, 300] // [x, y] pixels\n});\n\nif (result.found) {\n  console.log('Vehicle:', result.vehicle_info);\n  console.log('Confidence:', result.confidence);\n  console.log('Track ID:', result.track_id);\n} else {\n  console.log('No vehicle found:', result.message);\n}\n```\n\n### Track Queries & Subscriptions\n\n#### Query Tracks\n\nQuery tracks by VIN number.\n\n```typescript\nconst result = await client.queryTracks({\n  vin_number: \"1HGBH41JXMN109186\"\n});\n\nconsole.log(`Found ${result.count} tracks`);\nresult.tracks.forEach(track => {\n  console.log('Track ID:', track.track_id);\n  console.log('Violation tags:', track.violation_tags);\n});\n```\n\n#### Add Subscription\n\nCreate a subscription to receive notifications when tracks matching certain criteria are found.\n\n```typescript\nconst subscription = await client.addSubscription({\n  violation_only: true,\n  filter_attributes: {\n    vin_number: [\"1HGBH41JXMN109186\"],\n    road_city: [\"San Francisco\"],\n    gps_trajectory: [\"POLYGON((lon1 lat1, lon2 lat2, ...))\"]\n  }\n});\n\nconsole.log('Subscription ID:', subscription.subscription_id);\n```\n\n#### Modify Subscription\n\nModify an existing subscription.\n\n```typescript\n// Add a filter target\nawait client.modifySubscription({\n  subscription_id: \"subscription-id\",\n  modification_type: \"add_filter_target\",\n  filter_attributes: {\n    vin_number: [\"NEWVIN123456789\"]\n  }\n});\n\n// Clear a filter\nawait client.modifySubscription({\n  subscription_id: \"subscription-id\",\n  modification_type: \"clear_filter\",\n  filter_attributes: {\n    vin_number: []\n  }\n});\n\n// Set violation_only flag\nawait client.modifySubscription({\n  subscription_id: \"subscription-id\",\n  modification_type: \"set_violation_only\",\n  violation_only: false\n});\n```\n\n#### Delete Subscription\n\n```typescript\nconst result = await client.deleteSubscription({\n  subscription_id: \"subscription-id\"\n});\n\nconsole.log('Deleted:', result.deleted);\n```\n\n#### List Subscriptions\n\n```typescript\n// List without targets\nconst result = await client.listSubscriptions();\n\n// List with targets included\nconst resultWithTargets = await client.listSubscriptions({\n  include_targets: true\n});\n\nresultWithTargets.subscriptions.forEach(sub => {\n  console.log('Subscription:', sub.subscription_id);\n  if (sub.vin_number) {\n    console.log(`VIN targets: ${sub.vin_number.target_count}`);\n    if (sub.vin_number.targets) {\n      console.log('VINs:', sub.vin_number.targets);\n    }\n  }\n});\n```\n\n### Violation Proposals & Labeling\n\n#### Propose Violations\n\n```typescript\nconst result = await client.proposeViolations({\n  video_id: 'video-id',\n  violations: [\n    {\n      vehicle_id: 2,\n      violation_tags: ['speeding', 'reckless'],\n      severity: 2, // 0=minor, 1=moderate, 2=severe\n      description: 'Vehicle was speeding and driving recklessly',\n      confidence: 0.85\n    }\n  ]\n});\n\nconsole.log('Proposals:', result.results);\n```\n\n#### Query Violation Proposal\n\nQuery the status and results of a violation proposal. This endpoint is meant to supplement webhooks as a fallback mechanism for state synchronization and reconciliation. Use webhooks for real-time notifications, and this endpoint to query current state when needed.\n\n```typescript\nconst proposal = await client.queryViolationProposal({\n  proposal_id: \"proposal-id\"\n});\n\nconsole.log('Status:', proposal.proposal.status);\nconsole.log('Violation tags:', proposal.proposal.violation_tags);\n\n// If processed, labeled violation is included\nif (proposal.labeled_violation) {\n  console.log('Labeled violation:', proposal.labeled_violation);\n}\n```\n\n#### Claim and Submit Labeling Task\n\n```typescript\n// Claim a task\nconst task = await client.claimLabelingTask();\n\nif ('task_id' in task) {\n  console.log('Claimed task:', task.task_id);\n  console.log('Spec:', task.spec_json);\n\n  // Submit labeling result\n  await client.submitLabelingResult({\n    task_id: task.task_id,\n    label_json: {\n      proposal_result: 'accepted',\n      violation_tags: ['speeding'],\n      confidence: 0.9,\n      severity: 2,\n      notes: 'Clear evidence of speeding'\n    }\n  });\n} else {\n  console.log('No tasks available:', task.message);\n}\n```\n\n#### Request Violation Relabeling\n\nRequest a relabeling of an existing violation.\n\n```typescript\nconst result = await client.requestViolationRelabeling({\n  track_id: \"track-id\",\n  relabeling_suggestion: {\n    violation_tags: [\"speeding\", \"reckless\"],\n    severity: 2,\n    confidence: 0.95,\n    description: \"Updated violation description\"\n  }\n});\n\nconsole.log('Relabel ID:', result.relabel_id);\n```\n\n#### Query Violation Relabeling\n\nQuery the status and results of a violation relabeling request. This endpoint is meant to supplement webhooks as a fallback mechanism for state synchronization and reconciliation. Use webhooks for real-time notifications, and this endpoint to query current state when needed.\n\n```typescript\nconst relabeling = await client.queryViolationRelabeling({\n  relabel_id: \"relabel-id\"\n});\n\nconsole.log('Status:', relabeling.status);\nconsole.log('Requested at:', relabeling.requested_at);\nconsole.log('Request diff:', relabeling.request_diff);\n\nif (relabeling.status === \"approved\" || relabeling.status === \"edited\") {\n  console.log('Processed at:', relabeling.processed_at);\n  console.log('Result diff:', relabeling.result_diff);\n} else if (relabeling.status === \"rejected\") {\n  console.log('Rejection message:', relabeling.rejection_message);\n}\n```\n\n### Admin Operations\n\nFor admin operations, use the `AllRoadsAdminClient`:\n\n```typescript\nimport { AllRoadsAdminClient } from '@allroads/client';\n\nconst adminClient = new AllRoadsAdminClient({\n  baseUrl: 'https://xxx.execute-api.us-west-2.amazonaws.com/Prod',\n  adminApiKey: 'your-admin-api-key'\n});\n\n// Create a new user\nconst user = await adminClient.createUser('alice');\nconsole.log('User ID:', user.user_id);\n\n// Create an API key for the user\nconst apiKey = await adminClient.createApiKey('alice');\nconsole.log('API Key:', apiKey.api_key);\n\n// Revoke an API key\nawait adminClient.revokeApiKey('alice', apiKey.api_key);\n```\n\n## Error Handling\n\nThe client throws typed errors for different failure scenarios:\n\n```typescript\nimport { AllRoadsClient, AllRoadsApiError, AllRoadsNetworkError } from '@allroads/client';\n\ntry {\n  await client.indexVideoSegment({ /* ... */ });\n} catch (error) {\n  if (error instanceof AllRoadsApiError) {\n    console.error('API Error:', error.message);\n    console.error('Status Code:', error.statusCode);\n    \n    if (error.isAuthError()) {\n      console.error('Invalid API key');\n    } else if (error.isForbiddenError()) {\n      console.error('Insufficient permissions');\n    } else if (error.isValidationError()) {\n      console.error('Invalid request parameters');\n    } else if (error.isServerError()) {\n      console.error('Server error - please retry');\n    }\n  } else if (error instanceof AllRoadsNetworkError) {\n    console.error('Network Error:', error.message);\n  }\n}\n```\n\n## TypeScript Support\n\nAll request and response types are exported:\n\n```typescript\nimport type {\n  IndexVideoSegmentRequest,\n  IndexVideoSegmentResponse,\n  QueryVehicleInfoRequest,\n  QueryVehicleInfoResponse,\n  VehicleInfo,\n  ViolationSeverity,\n  // ... and more\n} from '@allroads/client';\n```\n\n## Configuration Options\n\n```typescript\nconst client = new AllRoadsClient({\n  // Required\n  baseUrl: 'https://xxx.execute-api.us-west-2.amazonaws.com/Prod',\n  apiKey: 'your-api-key',\n  \n  // Optional\n  timeout: 60000 // Request timeout in ms (default: 30000)\n});\n```\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Build\nnpm run build\n\n# Type check\nnpm run typecheck\n\n# Watch mode\nnpm run dev\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}