{"_id":"@anisprouts/dsp-sdk-trial","_rev":"2-ed325f74560227110219cf0505a8b5af","name":"@anisprouts/dsp-sdk-trial","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@anisprouts/dsp-sdk-trial","version":"0.1.0","keywords":["sprouts","dsp","data-platform","search","sdk","api-client"],"license":"MIT","_id":"@anisprouts/dsp-sdk-trial@0.1.0","maintainers":[{"name":"anisprouts","email":"aniruddha.maradwar@sprouts.ai"}],"dist":{"shasum":"0cd940242aa338cdaf63cd6bbd5b3e87771344a9","tarball":"https://registry.npmjs.org/@anisprouts/dsp-sdk-trial/-/dsp-sdk-trial-0.1.0.tgz","fileCount":11,"integrity":"sha512-Uu1Te4ezb+J7jOOMmyOrM6I7b77Mc0Uc3LEtIdFsh3/V74OFa5Gq/Dd/lBBBOxuLCtWXFc+lHABzJ7G8R54PBw==","signatures":[{"sig":"MEUCIQCEjc3+m4sU7BP5u3+HRiHRxa5OtJwXel/knnkKBsLocgIgNQrNV6SVGc/oWLYCsYxANdYEtE8GfjSdgDC6A3XEfJ4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":180626},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"scripts":{"test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run typecheck && npm run test && npm run build"},"_npmUser":{"name":"anisprouts","email":"aniruddha.maradwar@sprouts.ai"},"_npmVersion":"11.13.0","description":"Trial JavaScript/TypeScript SDK for the Sprouts Data Platform (DSP) API: search, look-alike (similar), and key usage.","directories":{},"sideEffects":false,"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.2.0","vitest":"^2.1.0","typescript":"^5.5.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/dsp-sdk-trial_0.1.0_1786607092508_0.6580509227034184","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@anisprouts/dsp-sdk-trial","version":"0.2.0","description":"Trial JavaScript/TypeScript SDK for the Sprouts Data Platform (DSP) API: search, look-alike (similar), entity lookups, and key usage.","license":"MIT","type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"sideEffects":false,"engines":{"node":">=18.0.0"},"publishConfig":{"access":"public"},"scripts":{"build":"tsup","typecheck":"tsc --noEmit","test":"vitest run","test:watch":"vitest","prepublishOnly":"npm run typecheck && npm run test && npm run build"},"keywords":["sprouts","dsp","data-platform","search","entities","enrichment","sdk","api-client"],"devDependencies":{"@types/node":"^20.14.0","tsup":"^8.2.0","typescript":"^5.5.0","vitest":"^2.1.0"},"_id":"@anisprouts/dsp-sdk-trial@0.2.0","_nodeVersion":"24.16.0","_npmVersion":"11.13.0","dist":{"integrity":"sha512-3FECVxS7dUrtRRj0VvI7am/vx/i6vZTAo8SWMr8dIwITYhii10cdfXzFzrXEqKli0gaHkCYmzGtIBBykpwKQ0Q==","shasum":"18649a6070600d26f052250167604d76ef4205c6","tarball":"https://registry.npmjs.org/@anisprouts/dsp-sdk-trial/-/dsp-sdk-trial-0.2.0.tgz","fileCount":11,"unpackedSize":256874,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAv88GmzT53DmCNQTBSyeUlfeBz/z2TE+F5ALhNDeuinAiEA0gBla8Fwj/DLNS5lIct0wzgf9J/2a+Ho2BmCJVYzIDs="}]},"_npmUser":{"name":"anisprouts","email":"aniruddha.maradwar@sprouts.ai"},"directories":{},"maintainers":[{"name":"anisprouts","email":"aniruddha.maradwar@sprouts.ai"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dsp-sdk-trial_0.2.0_1786650449604_0.32260691574812417"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-13T07:44:52.411Z","modified":"2026-08-13T19:47:29.921Z","0.1.0":"2026-08-13T07:44:52.625Z","0.2.0":"2026-08-13T19:47:29.735Z"},"license":"MIT","keywords":["sprouts","dsp","data-platform","search","entities","enrichment","sdk","api-client"],"description":"Trial JavaScript/TypeScript SDK for the Sprouts Data Platform (DSP) API: search, look-alike (similar), entity lookups, and key usage.","maintainers":[{"name":"anisprouts","email":"aniruddha.maradwar@sprouts.ai"}],"readme":"# @anisprouts/dsp-sdk-trial\n\nOfficial JavaScript / TypeScript SDK for the **Sprouts Data Platform (DSP) API**.\n\nCovers the API-key surface:\n\n| Method | Endpoint | Scope |\n|---|---|---|\n| `client.search(params)` | `POST /v1/search` | `dsp.search.read` |\n| `client.similar(params)` | `POST /v1/similar` | `dsp.search.read` |\n| `client.entities.*(params)` | `POST /v1/entities/{category}` | `dsp.entities.read` |\n| `client.usage(params?)` | `GET /v1/keys/usage` | `dsp.usage.read` |\n\nZero runtime dependencies. Node.js ≥ 18 (uses the built-in `fetch`). Ships ESM\nand CJS with full TypeScript types.\n\n> 📘 New to the platform? Start with the **[User Guide](./USER_GUIDE.md)** —\n> the full journey from getting an API key to production troubleshooting.\n> This README is the quick reference.\n\n## Install\n\n```sh\nnpm install @anisprouts/dsp-sdk-trial\n```\n\n## Quick start\n\n```ts\nimport { DspClient } from '@anisprouts/dsp-sdk-trial';\n\nconst client = new DspClient({\n  apiKey: process.env.DSP_API_KEY, // sk_dsp_live_… or sk_dsp_test_…\n});\n\nconst page = await client.search({\n  query: 'industrial robotics companies in Germany',\n  mode: 'auto',\n  category: 'company',\n  limit: 25,\n});\n\nfor (const hit of page.results) {\n  console.log(hit.id, hit.score, hit['name']);\n}\n```\n\n`apiKey` defaults to the `DSP_API_KEY` environment variable, and `baseUrl` to\n`DSP_BASE_URL` (falling back to the QA environment,\n`https://dsp.gtmsprouts.ai/backend`).\n\n> **Server-side only.** DSP keys carry your tenant's whole credit balance, and\n> the API refuses any browser request carrying a key\n> (`403 auth.browser_origin`). The client throws if constructed in a browser;\n> call it from your server and have your frontend call you.\n\n## Look-alike search\n\n```ts\nconst lookalikes = await client.similar({\n  anchors: [\n    { value: 'acme.com' },                          // by: 'domain' is the default\n    { value: 'Globex', by: 'name', weight: 0.5 },\n  ],\n  combine: 'and', // 'and' = like all anchors together; 'or' = like any one\n  limit: 50,\n});\n```\n\n## Entity lookup\n\nFetch full records by id — one method per category: `companies`, `persons`,\n`patents`, `news`, `trends`, `marketReports`, `fundings`, `academicReports`,\n`jobOpenings`. Responses are fully typed (`CompanyRecord`, `PatentRecord`, …)\nand billed per requested id.\n\n```ts\nconst page = await client.entities.companies({\n  ids: ['000006dddc0f7a39', 'definitely_not_real'],\n  fields: ['account_name', 'industry', 'employee_count'], // omit for the full record\n});\n\nfor (const hit of page.results) {\n  if (!hit.found) continue; // misses are returned, never silently dropped\n  console.log(hit.fields.account_name, hit.fields.employee_count);\n}\n```\n\n`companies` and `persons` can also resolve **raw identifiers** instead of\nplatform ids — set `by` (≤ 50 ids per call in that mode):\n\n```ts\nconst byDomain = await client.entities.companies({\n  ids: ['adyen.com', 'checkout.com'],\n  by: 'domain', // 'auto' | 'domain' | 'li_url' | 'name' ('domain' not valid for persons)\n});\n```\n\nBatch limits: 1000 ids per call for companies/persons, 100 for the document\ncategories (document records are large), 50 whenever `by` is set.\n\n## Usage (the calling key's spend)\n\n```ts\nconst usage = await client.usage({\n  granularity: 'day',                 // 'hour' | 'day' | 'month' | 'total'\n  from: new Date('2026-07-01'),       // Date or ISO string\n  to: new Date('2026-08-01'),\n});\nconsole.log(usage.total_requests, usage.total_credits, usage.buckets);\n```\n\nDefaults to the last 30 days, bucketed by day. `total_credits` is net of\nrefunds. Only the calling key's usage is readable.\n\n## Pagination\n\nResults are cursor-paginated (`next_cursor` is opaque and signed; there is no\npage/offset parameter). Either follow it yourself:\n\n```ts\nlet cursor: string | undefined;\ndo {\n  const page = await client.search({ query: 'fintech', cursor });\n  process(page.results);\n  cursor = page.next_cursor ?? undefined;\n} while (cursor);\n```\n\n…or use the async iterators:\n\n```ts\nfor await (const page of client.searchPages({ query: 'fintech', limit: 100 })) {\n  process(page.results);\n}\n// client.similarPages(...) works the same way.\n```\n\nDo not change filters mid-pagination — the server rejects the cursor\n(`pagination.cursor_invalid`) rather than silently reshuffling results.\n\n## Error handling\n\nEvery non-2xx response is an RFC 9457 problem, surfaced as a typed error.\n`error.code` is a stable machine-readable string and `error.requestId` is the\nhandle to quote when contacting support.\n\n```ts\nimport {\n  APIError,\n  APIConnectionError,\n  AuthenticationError,\n  PermissionDeniedError,\n  InsufficientCreditsError,\n  RateLimitError,\n  BadRequestError,\n  DspValidationError,\n  ErrorCode,\n} from '@anisprouts/dsp-sdk-trial';\n\ntry {\n  await client.search({ query: 'fintech' });\n} catch (err) {\n  if (err instanceof RateLimitError) {\n    // 429 — quota.* ; err.retryAfter is the Retry-After header in seconds\n  } else if (err instanceof InsufficientCreditsError) {\n    // 402 credits.insufficient — waiting does not help; top up credits\n  } else if (err instanceof PermissionDeniedError) {\n    // 403 — usually auth.insufficient_scope: the key lacks a scope\n  } else if (err instanceof AuthenticationError) {\n    // 401 — key missing, unknown, revoked, or expired\n  } else if (err instanceof BadRequestError) {\n    // 400/422 — fix the request; err.problem.extra may carry specifics\n  } else if (err instanceof APIConnectionError) {\n    // network failure or timeout — no response was received\n  } else if (err instanceof DspValidationError) {\n    // the SDK rejected the call locally; nothing was sent\n  }\n}\n```\n\n| Error class | Status | Typical `code` |\n|---|---|---|\n| `DspValidationError` | — (not sent) | — |\n| `BadRequestError` | 400 / 422 | `request.invalid`, `pagination.cursor_invalid` |\n| `AuthenticationError` | 401 | `auth.unauthorized`, `auth.invalid_key`, `auth.expired` |\n| `InsufficientCreditsError` | 402 | `credits.insufficient` |\n| `PermissionDeniedError` | 403 | `auth.insufficient_scope`, `auth.browser_origin` |\n| `NotFoundError` | 404 | — |\n| `ConflictError` | 409 | `idempotency.*` |\n| `RateLimitError` | 429 | `quota.*` (has `retryAfter`) |\n| `InternalServerError` | 5xx | `upstream.*`, `auth.unavailable`, `internal` |\n| `APITimeoutError` | — | request exceeded `timeoutMs` |\n| `APIConnectionError` | — | network failure |\n\nThe full closed set of codes is exported as `ErrorCode`.\n\n## Retries, timeouts, aborts\n\nConnection errors, timeouts, and `429 / 502 / 503 / 504` responses are retried\nwith exponential backoff and jitter, honoring `Retry-After`. Defaults: 2\nretries, 60 s per attempt. All endpoints here are reads, so retries cannot\ndouble-charge.\n\n```ts\nconst client = new DspClient({ maxRetries: 3, timeoutMs: 30_000 });\n\n// Per request:\nconst controller = new AbortController();\nawait client.search(\n  { query: 'fintech' },\n  { maxRetries: 0, timeoutMs: 5_000, signal: controller.signal },\n);\n```\n\n## Reading responses honestly\n\nThe envelope carries fields worth checking, not just `results`:\n\n- `total_is_estimate` — when true, `total` is an estimate.\n- `degradation[]` — what the server *couldn't* do for this request (a corpus\n  timed out, vector coverage incomplete, pagination truncated…). Empty means\n  \"checked, nothing degraded\".\n- `meta.environment` — `live` or `test`, echoed so a test-key result can never\n  be mistaken for a live one.\n- `meta.request_id` — quote it in any support conversation.\n\n## Development\n\n```sh\nnpm install\nnpm run typecheck\nnpm test\nnpm run build\n```\n","readmeFilename":"README.md"}