@wavebirdai/api 0.1.0-beta.12 → 0.1.0-beta.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,100 +1,46 @@
1
- # @wavebirdai/api
1
+ # wavebird API
2
2
 
3
- Add Wavebird Banner, Native, and Clip placements to an authenticated chat app. The package provides server handlers for placement, consent, and generation reporting, plus a browser adapter for the hosted renderer. Your server keeps the Wavebird key; your app keeps control of its login, model stream, layout, and consent choice.
3
+ Integrate Banner, Native and Clip ads into your AI app. wavebird handles ad delivery and consent. Your app keeps its existing login, model and result display.
4
4
 
5
- ## Integrate with Next.js
5
+ [API docs](https://wavebird.ai/api/quickstart) | [Dashboard](https://dashboard.wavebird.ai/wavebird) | [Troubleshooting](https://wavebird.ai/api/troubleshooting)
6
6
 
7
- You need a saved Wavebird Test project and placement in Dashboard, a Server Test Key, an existing authenticated Next.js App Router app, and a durable turn store. Start with the placement's saved formats, sizes, timing, and consent mode. Test traffic is nonpayable.
7
+ ## Choose your language
8
8
 
9
- 1. Install the package and generate the route files for your app directory:
9
+ | Language | Package and guide |
10
+ | --- | --- |
11
+ | JavaScript | `@wavebirdai/api`, follow the steps below |
12
+ | TypeScript | `@wavebirdai/api`, with included types and TypeScript examples |
13
+ | Python | `wavebird-publisher-server`, follow the [Python guide](python/README.md) |
10
14
 
11
- ```sh
12
- npm install @wavebirdai/api@0.1.0-beta.12
13
- ./node_modules/.bin/wavebird-next init --lang ts --root . --app-dir src/app
14
- ```
15
-
16
- Use `--lang js --app-dir app` for a JavaScript app with `app/` at the project root. The generator adds files without overwriting existing ones and writes `WAVEBIRD-SETUP.md` with the exact connection points.
17
-
18
- 2. Set the server-only values in your deployment environment:
15
+ Native iOS and Android packages are not currently available. See [integration paths](https://wavebird.ai/api/integration-paths) for supported environments.
19
16
 
20
- ```dotenv
21
- WAVEBIRD_CLIENT_ID=<saved-project-id>
22
- WAVEBIRD_SECRET_KEY=<server-test-key>
23
- WAVEBIRD_PREFERENCE_SECRET=<stable-random-value-at-least-32-bytes>
24
- WAVEBIRD_PUBLIC_ORIGINS=https://your-app.example
25
- ```
26
-
27
- `WAVEBIRD_PUBLIC_ORIGINS` must contain each exact app origin, including scheme and port. For local Server Test-key work, add the exact loopback origin to this list while keeping the Dashboard project domain at its real HTTPS host. Never expose the server key or preference secret through `NEXT_PUBLIC_`, client props, or source control.
28
-
29
- 3. Connect the generated files to your app: copy the **saved** placement settings into `lib/publisher`; have `lib/auth` validate the real logged-in request and return a stable, non-credential session ID; replace `lib/turn-store` with your persistent store; and connect `lib/model` to your existing generation stream. The supplied auth, store, and model hooks fail closed until you do this. If you use PostgreSQL, the provided adapter uses your existing pool and its `install()` belongs in your normal migration step.
17
+ ## Set up JavaScript or TypeScript
30
18
 
31
- The generated server route keeps the Wavebird key on the server and wraps your existing stream:
19
+ Use Node.js 20 or later on your server.
32
20
 
33
- ```ts
34
- import { getPublisher } from "../../../lib/publisher";
35
- import { existingGeneration } from "../../../lib/model";
36
-
37
- export async function POST(request: Request): Promise<Response> {
38
- return getPublisher().withGeneration({ request, run: existingGeneration });
39
- }
40
- ```
21
+ 1. **Open your project in Dashboard.** Choose your language and package version. Save your HTTPS app URL and approved origins. `www.example.com` and `example.com` are separate origins.
22
+ 2. **Install the package.** Run this in your app's terminal, in the folder containing `package.json`:
41
23
 
42
- 4. Mount the generated `WavebirdPlacement` beside your app's result area using real authenticated user and conversation IDs, then wrap the existing generation request:
43
-
44
- ```tsx
45
- <WavebirdPlacement
46
- clientId={publicProjectId}
47
- userId={authenticatedUserId}
48
- conversationId={activeConversationId}
49
- onReady={setAds}
50
- />
51
-
52
- await ads.connectGeneration({
53
- signal,
54
- request: headers => fetch("/api/generate", { method: "POST", headers, signal }),
55
- consume: async (response, lifecycle) => {
56
- if (!response.ok || !response.body) throw new Error("generation_unavailable");
57
- const reader = response.body.getReader();
58
- while (true) {
59
- const next = await reader.read();
60
- if (next.done) break;
61
- // Forward next.value to your existing stream consumer.
62
- lifecycle.onDelta();
63
- }
64
- },
65
- });
24
+ ```sh
25
+ npm install @wavebirdai/api@0.1.0-beta.12
66
26
  ```
67
27
 
68
- The generated `WAVEBIRD-SETUP.md` shows where the component and routes go. Use Wavebird's consent dialog only when that matches the saved project; for `own_cmp`, connect your actual CMP lifecycle.
69
-
70
- 5. Validate in Test: confirm the saved format and size, consent and GPC behavior, No-Fill, Stop/abort, and late responses. The generation result must continue independently of the ad path. Move to another package version or Live only through your normal project approval process.
71
-
72
- JavaScript and TypeScript use this same package. Complete Next.js JavaScript and TypeScript examples are included in `node_modules/@wavebirdai/api/examples/next-js` and `node_modules/@wavebirdai/api/examples/next-ts`. For other frameworks, use the explicit `@wavebirdai/api/server` and `@wavebirdai/api/browser` exports described below. The [REST reference](https://wavebird.ai/api/reference/endpoints) covers integrations without this package. The established [`wavebird`](https://www.npmjs.com/package/wavebird) SDK is a separate package.
73
-
74
- ## Server and browser boundary
75
-
76
- `@wavebirdai/api/server` exports `createPublisherServer`. Configure it with server-only Project ID, Server Test or production Key, preference signing secret, the publisher's real request authorization function, exact `publicOrigins`, and the saved project/placement values shown in the dashboard. The origin list is required. The package compares the browser Origin with a configured public origin whose host matches the route Host, even when Next.js or a proxy gives the route an internal URL. `localhost` and `127.0.0.1` are separate origins, and each port and scheme must match exactly; HTTP loopback is available only with a Server Test Key. A production key also requires its separately approved project and Wavebird server authority. Omit `bidfloor` and `bidfloorCurrency` to inherit saved pricing. An explicit override supplies both a nonnegative amount, including zero, and a three-letter currency; the API validates it against the saved project. It returns authenticated `placementPOST`, `consentGET`, `consentPOST`, and `withGeneration` handlers, plus the server-only `reportGeneration(jobId, event)` method. The helper constructs the existing `/v1/placements`, `/v1/consent`, and `/v1/jobs/{id}/generation/{event}` requests; it does not introduce a new Wavebird protocol. The Wavebird API remains authoritative for saved scope, creative formats, duration, fallback, and financial classification.
77
-
78
- Responsive size selection is enabled by default in this version. The browser adapter sends the measured reserved container size. The server chooses one of the saved `allowedSizes` that fits, or returns `no_fit` without an upstream placement request. Numeric `maxWidth` and `maxHeight` are optional advanced caps: when omitted, the saved sizes define the envelope; when supplied, they can only narrow eligible sizes. A size can carry `formats: ["banner"]`, `formats: ["native"]`, `formats: ["clip"]`, or an approved combination; this annotation remains on the publisher server and is stripped from the wavebird request. A browser format preference is accepted only when it is among the saved `allowedFormats` and compatible with the selected size. Set `responsiveSizeSelection: false` only for a deliberate fixed-size compatibility integration. Reserve enough height for the selected creative and its controls; do not stretch the returned creative or place it over the model result.
79
-
80
- Create the server helper when a request arrives, as the included Next.js examples do. This lets Next.js build a publisher app without loading its server key into the build process; the helper still validates configuration before handling traffic.
81
-
82
- `withGeneration({ request, run, onLifecycle })` accepts an optional server-side observer. It receives `{ type, sessionId, generationId }` for `started` and one terminal state: `done`, `error`, or `abort`. Use it to forward lifecycle events to your own generation reporter; observer failures do not change the model response. It runs only for authenticated, same-origin requests with valid generation transport IDs. The callback is not awaited, and it receives no prompt or model bytes.
83
-
84
- With `sessionIdForRequest` and `turnJournal` configured, the package validates the browser non-credential session ID against the publisher authenticated request, binds one turn to its authorized placement job, and automatically retries ordered generation reports. The PostgreSQL adapter uses the publisher existing pool; run its `install()` in the normal migration step. An unavailable journal suppresses ad placement while an authenticated model request can still run. The store and HMAC key must survive worker restarts. A durable per-project key-version guard rejects a changed preference secret before accepting another turn; pending reports can still reconcile. Coordinate key rotation after active turns are drained rather than clearing the guard while turns remain. This opt-in path requires a package version that includes these exports; earlier published versions retain their original behavior.
28
+ 3. **Save the Server ENV.** Add the values from Dashboard to your server environment. Keep `WAVEBIRD_SECRET_KEY` and `WAVEBIRD_PREFERENCE_SECRET` out of browser code and Git.
29
+ 4. **Connect the backend and frontend code.** Follow Dashboard's generated files to connect your app session, durable turn storage, model stream and ad slot. Keep the saved formats, sizes and timing.
30
+ 5. **Run your first Test ad.** Confirm that the ad appears and the request is recorded in Test Logs. Check that generation still works with declined consent, no available ad and Stop.
85
31
 
86
- Call `reportGeneration` only from trusted server code with a job ID returned by an authorized placement. Its events are `started`, `finished`, and `failed`. The server key scopes the request at wavebird; invalid IDs or events are rejected locally, and each report has a five-second deadline and a parallel request limit. Reporting errors reject the returned promise so the caller can handle them outside the model response path.
32
+ Test ads are nonpayable. Complete the [Live prerequisites](https://wavebird.ai/api/guides/going-live) before requesting Live activation.
87
33
 
88
- `@wavebirdai/api/browser` exports the existing tested `createPublisherAds` and `connectPublisherGeneration` lifecycle helper. Pass the mount's `ads` instance as the fourth `connectPublisherGeneration` argument when more than one surface can run; the original three-argument global lookup remains for older integrations. It loads the hosted renderer and attaches only to a reserved container selected by the publisher. Initialize it with the current app user and conversation IDs; pass optional same-origin `placementEndpoint` and `consentEndpoint` paths when using the server routes in this package. The helper forwards those paths to the hosted renderer. Keep the Server Key and preference signing secret in the server configuration; never pass them as browser options. Use the real wavebird consent dialog or the publisher's actual CMP. Consent on an idle page does not request an ad. For `during`, the helper displays only during an active generation. Its generation request and response stream run without waiting for consent synchronization, the ad response, or renderer readiness. It clears late responses on completion, error, abort, conversation change, GPC, or withdrawal.
34
+ For Next.js, you can use the [generator](docs/web/nextjs.md) instead of copying Dashboard's route files.
89
35
 
90
- For `after`, resolve the generation consumer only after your app presents the result. The browser helper waits for both the transport finish and that consumer before starting the placement. If presentation fails, reject the consumer so the placement does not start.
36
+ ## Connect your model output
91
37
 
92
- ## Next.js
38
+ Use `@wavebirdai/api/server` on the server and `@wavebirdai/api/browser` for the ad slot. Your response consumer must display the model output and finish only after the result is visible.
93
39
 
94
- The package contains equivalent JavaScript and TypeScript Next.js example files in `examples/next-js` and `examples/next-ts`. Each shows a publisher-owned reserved slot outside the input and scrolling transcript, same-origin consent and placement routes, the server-only configuration, and an existing generation stream wrapped by `withGeneration`. Their authorization hook fails closed until connected to the publisher's actual session validation. The sample generation stream is a local demonstration and is meant to be replaced by the publisher's existing model call.
40
+ [JavaScript and TypeScript examples](docs/web/generation.md) | [Server and browser reference](docs/web/reference.md)
95
41
 
96
- The required server-only values are `WAVEBIRD_CLIENT_ID`, `WAVEBIRD_SECRET_KEY`, `WAVEBIRD_PREFERENCE_SECRET`, and `WAVEBIRD_PUBLIC_ORIGINS`. Keep secrets outside browser bundles and source control. Set project surface, placement, job type, timing, formats, locale, consent profile, identity/domain, and ad-space dimensions from the saved dashboard configuration. Reserve space for the selected creative and controls without distorting it. The publisher positions the section in its own UI.
42
+ ## Update an existing integration
97
43
 
98
- ## Test scope
44
+ Keep your installed version until you choose to upgrade. Follow the [migration guide](https://wavebird.ai/api/reference/versioning) and check the affected integration before deployment. The older `wavebird` npm package uses a different integration path.
99
45
 
100
- The browser and generation transport sources are included in the package. Before use in a publisher app, test the server routes, browser placement, consent, and generation lifecycle against its saved Test project and supported browser and host. Test traffic must remain nonpayable; installing this package does not activate Live ads.
46
+ [Configuration](https://wavebird.ai/api/configuration) | [REST reference](https://wavebird.ai/api/reference/endpoints) | [Report an issue](https://github.com/wavebird-ai/api/issues)
@@ -0,0 +1,58 @@
1
+ # Connect generation to the displayed result
2
+
3
+ These are connection helpers, not complete apps. Use the same installed `@wavebirdai/api@0.1.0-beta.12` as your server routes.
4
+
5
+ - `ads` is the instance for this surface, returned by `createPublisherAds` or the generated component's `onReady` callback.
6
+ - `sendExistingRequest` sends your existing authenticated model request. Merge the provided headers into its headers and preserve its body and abort signal. Call the route wrapped by `withGeneration`.
7
+ - `consumeAndPresentResponse` is your existing response parser and UI consumer. Call `onDelta` as output becomes visible. Call `onPresented` when the result is presented. Resolve after presentation, and reject on failure. For an image, do not report progress before the result is displayed.
8
+
9
+ ## TypeScript
10
+
11
+ ```ts
12
+ import type { PublisherAds, GenerationConsumer } from "@wavebirdai/api/browser";
13
+
14
+ export function runGeneration<T>(
15
+ ads: PublisherAds,
16
+ signal: AbortSignal,
17
+ sendExistingRequest: (
18
+ headers: Record<string, string>, signal: AbortSignal
19
+ ) => Promise<Response>,
20
+ consumeAndPresentResponse: GenerationConsumer<T>
21
+ ): Promise<T> {
22
+ return ads.connectGeneration({
23
+ signal,
24
+ request: headers => sendExistingRequest(headers, signal),
25
+ consume: (response, lifecycle) => consumeAndPresentResponse(response, {
26
+ onDelta: lifecycle.onDelta,
27
+ onPresented: () => lifecycle.onPresented?.(),
28
+ }),
29
+ });
30
+ }
31
+ ```
32
+
33
+ ## JavaScript
34
+
35
+ ```js
36
+ export function runGeneration(
37
+ ads, signal, sendExistingRequest, consumeAndPresentResponse
38
+ ) {
39
+ return ads.connectGeneration({
40
+ signal,
41
+ request: headers => sendExistingRequest(headers, signal),
42
+ consume: (response, lifecycle) => consumeAndPresentResponse(response, {
43
+ onDelta: lifecycle.onDelta,
44
+ onPresented: () => lifecycle.onPresented?.(),
45
+ }),
46
+ });
47
+ }
48
+ ```
49
+
50
+ The optional call preserves model-only responses, which do not provide an ad presentation callback in this package version. It does not convert failed advertising into a successful ad result.
51
+
52
+ ## Timing and cleanup
53
+
54
+ For `after`, the helper waits for the transport to finish and the consumer to resolve before requesting placement. Receiving the final byte is not the same as presenting the result.
55
+
56
+ For `during`, placement runs alongside generation. Retention depends on the format and surface. Do not add an unconditional stream-end hide action for all ads. The hosted renderer owns creative behavior, and the package enables Clip cleanup after playback. Follow the saved timing and the [format contract](https://wavebird.ai/api/concepts/ad-formats).
57
+
58
+ Pass the app's abort signal, update the conversation binding on conversation changes, and call `dispose()` on sign-out or surface teardown. Do not wait for renderer readiness before allowing model generation.
@@ -0,0 +1,36 @@
1
+ # Next.js generator
2
+
3
+ Use this path instead of copying Dashboard's route files. It supports an existing Next.js App Router app with JavaScript or TypeScript. Use the saved Dashboard configuration in either path.
4
+
5
+ ## Generate files
6
+
7
+ From the folder containing `package.json`:
8
+
9
+ ```sh
10
+ npm install @wavebirdai/api@0.1.0-beta.12
11
+ ./node_modules/.bin/wavebird-next init --lang ts --root . --app-dir src/app
12
+ ```
13
+
14
+ For JavaScript, use `--lang js`. For a root-level `app/` directory, use `--app-dir app`. The generator does not overwrite existing files. Read the generated `WAVEBIRD-SETUP.md` for their locations.
15
+
16
+ ## Connect your app
17
+
18
+ | Generated area | Your connection |
19
+ | --- | --- |
20
+ | `lib/publisher` | Server ENV and the saved project's placement configuration |
21
+ | `lib/auth` | Validate the real request session and return a stable, non-credential session ID |
22
+ | `lib/turn-store` | Durable atomic turn storage. The PostgreSQL adapter uses your existing pool. Run its `install()` through your normal migration process. |
23
+ | `lib/model` | Your existing abortable model request and response stream |
24
+ | `WavebirdPlacement` | A reserved slot beside the result, outside the input and scrolling transcript |
25
+
26
+ The auth, store and model hooks fail closed until connected. Do not replace authorization with `true`. Keep the preference signing secret stable across workers and restarts.
27
+
28
+ Mount `WavebirdPlacement` with the authenticated user and active conversation IDs. Use its `onReady` callback to retain the ads instance for that surface. Connect the generation request as shown in the [connection examples](generation.md). Keep request headers, body and cancellation from your app.
29
+
30
+ Use wavebird's consent dialog or your real CMP according to the project's saved consent mode. Do not grant consent from application startup code.
31
+
32
+ ## Check the result
33
+
34
+ Check visible ads and Test Logs, then No-Fill, denied consent, Stop and a conversation change. An ad failure must not prevent the model result. The complete framework examples are in `examples/next-js` and `examples/next-ts` inside the installed package. Their demonstration model must be replaced with your own.
35
+
36
+ [Return to setup](../../README.md#javascript-and-typescript) | [Configuration reference](reference.md)
@@ -0,0 +1,31 @@
1
+ # Web integration reference
2
+
3
+ Applies to `@wavebirdai/api@0.1.0-beta.12`. [Start with the integration steps](../../README.md#javascript-and-typescript).
4
+
5
+
6
+ `@wavebirdai/api/server` exports `createPublisherServer`. Configure it with server-only Project ID, Server Test or production Key, preference signing secret, the publisher's real request authorization function, exact `publicOrigins`, and the saved project/placement values shown in the dashboard. The origin list is required. The package compares the browser Origin with a configured public origin whose host matches the route Host, even when Next.js or a proxy gives the route an internal URL. `localhost` and `127.0.0.1` are separate origins, and each port and scheme must match exactly; HTTP loopback is available only with a Server Test Key. A production key also requires its separately approved project and wavebird server authority. Omit `bidfloor` and `bidfloorCurrency` to inherit saved pricing. An explicit override supplies both a nonnegative amount, including zero, and a three-letter currency; the API validates it against the saved project. It returns authenticated `placementPOST`, `consentGET`, `consentPOST`, and `withGeneration` handlers, plus the server-only `reportGeneration(jobId, event)` method. The helper constructs the existing `/v1/placements`, `/v1/consent`, and `/v1/jobs/{id}/generation/{event}` requests; it does not introduce a new wavebird protocol. The wavebird API remains authoritative for saved scope, creative formats, duration, fallback, and financial classification.
7
+
8
+ Responsive size selection is enabled by default in this version. The browser adapter sends the measured reserved container size. The server chooses one of the saved `allowedSizes` that fits, or returns `no_fit` without an upstream placement request. Numeric `maxWidth` and `maxHeight` are optional advanced caps: when omitted, the saved sizes define the envelope; when supplied, they can only narrow eligible sizes. A size can carry `formats: ["banner"]`, `formats: ["native"]`, `formats: ["clip"]`, or an approved combination; this annotation remains on the publisher server and is stripped from the wavebird request. A browser format preference is accepted only when it is among the saved `allowedFormats` and compatible with the selected size. Set `responsiveSizeSelection: false` only for a deliberate fixed-size compatibility integration. Reserve enough height for the selected creative and its controls; do not stretch the returned creative or place it over the model result.
9
+
10
+ Create the server helper when a request arrives, as the included Next.js examples do. This lets Next.js build a publisher app without loading its server key into the build process; the helper still validates configuration before handling traffic.
11
+
12
+ `withGeneration({ request, run, onLifecycle })` accepts an optional server-side observer. It receives `{ type, sessionId, generationId }` for `started` and one terminal state: `done`, `error`, or `abort`. Use it to forward lifecycle events to your own generation reporter; observer failures do not change the model response. It runs only for authenticated, same-origin requests with valid generation transport IDs. The callback is not awaited, and it receives no prompt or model bytes.
13
+
14
+ With `sessionIdForRequest` and `turnJournal` configured, the package validates the browser non-credential session ID against the publisher authenticated request, binds one turn to its authorized placement job, and automatically retries ordered generation reports. The PostgreSQL adapter uses the publisher existing pool; run its `install()` in the normal migration step. An unavailable journal suppresses ad placement while an authenticated model request can still run. The store and HMAC key must survive worker restarts. A durable per-project key-version guard rejects a changed preference secret before accepting another turn; pending reports can still reconcile. Coordinate key rotation after active turns are drained rather than clearing the guard while turns remain. These exports are included in `0.1.0-beta.12`. Earlier versions retain their original behavior.
15
+
16
+ Call `reportGeneration` only from trusted server code with a job ID returned by an authorized placement. Its events are `started`, `finished`, and `failed`. The server key scopes the request at wavebird; invalid IDs or events are rejected locally, and each report has a five-second deadline and a parallel request limit. Reporting errors reject the returned promise so the caller can handle them outside the model response path.
17
+
18
+ `@wavebirdai/api/browser` exports the `createPublisherAds` and `connectPublisherGeneration` lifecycle helper. Pass the mount's `ads` instance as the fourth `connectPublisherGeneration` argument when more than one surface can run; the original three-argument global lookup remains for older integrations. It loads the hosted renderer and attaches only to a reserved container selected by the publisher. Initialize it with the current app user and conversation IDs; pass optional same-origin `placementEndpoint` and `consentEndpoint` paths when using the server routes in this package. The helper forwards those paths to the hosted renderer. Keep the Server Key and preference signing secret in the server configuration; never pass them as browser options. Use the real wavebird consent dialog or the publisher's actual CMP. Consent on an idle page does not request an ad. For `during`, the helper starts placement with generation. The hosted renderer applies format-specific retention and cleanup, so `during` is not a universal instruction to hide every format when the stream ends. Its generation request and response stream run without waiting for consent synchronization, the ad response, or renderer readiness. It forwards completion, error, abort and conversation changes to the renderer. Consent withdrawal and GPC must suppress unauthorized advertising. Do not implement a second hide timer in the app or treat a hidden slot as proof of an ad blocker.
19
+
20
+ For `after`, resolve the generation consumer only after your app presents the result. The browser helper waits for both the transport finish and that consumer before starting the placement. If presentation fails, reject the consumer so the placement does not start.
21
+
22
+
23
+ ## Troubleshooting
24
+
25
+ - **401:** check the app session and server authorization before changing the wavebird key.
26
+ - **Origin rejected:** compare scheme, hostname and port with the saved project and server allowlist. `www.example.com` and `example.com` are separate origins.
27
+ - **No-Fill or `no_fit`:** keep the model result usable. Check saved formats and the measured slot size. Do not stretch a creative to force it to fit.
28
+ - **Empty frame:** record only the fixed error category and relative timing. HTTP 200 alone does not prove visible rendering. Never share signed URLs, headers, tokens or a HAR containing credentials.
29
+ - **After ad arrives too early:** resolve the result consumer after the UI has presented the result, not merely after the last network byte.
30
+
31
+ See [troubleshooting](https://wavebird.ai/api/troubleshooting) and [format behavior](https://wavebird.ai/api/concepts/ad-formats).
package/package.json CHANGED
@@ -1,17 +1,42 @@
1
1
  {
2
2
  "name": "@wavebirdai/api",
3
- "version": "0.1.0-beta.12",
3
+ "version": "0.1.0-beta.13",
4
4
  "private": false,
5
5
  "type": "module",
6
- "description": "Integrate Banner, Native, and Clip placements into authenticated chat apps with server-side keys, consent, and generation lifecycle handling",
6
+ "description": "JavaScript and TypeScript integration for wavebird Banner, Native and Clip ads, with consent and generation lifecycle handling.",
7
7
  "license": "MIT",
8
- "repository": { "type": "git", "url": "https://github.com/wavebird-ai/api" },
9
- "engines": { "node": ">=20" },
10
- "files": ["dist", "src", "build.mjs", "examples", "bin", "templates", "README.md", "LICENSE"],
11
- "bin": { "wavebird-next": "./bin/wavebird-next.mjs" },
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/wavebird-ai/api"
11
+ },
12
+ "engines": {
13
+ "node": ">=20"
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "src",
18
+ "build.mjs",
19
+ "examples",
20
+ "bin",
21
+ "templates",
22
+ "README.md",
23
+ "LICENSE",
24
+ "docs/web",
25
+ "python/README.md",
26
+ "python/examples/fastapi_app/README.md"
27
+ ],
28
+ "bin": {
29
+ "wavebird-next": "./bin/wavebird-next.mjs"
30
+ },
12
31
  "exports": {
13
- "./server": { "types": "./dist/server.d.ts", "import": "./dist/server.js" },
14
- "./browser": { "types": "./dist/browser.d.ts", "import": "./dist/browser.js" },
32
+ "./server": {
33
+ "types": "./dist/server.d.ts",
34
+ "import": "./dist/server.js"
35
+ },
36
+ "./browser": {
37
+ "types": "./dist/browser.d.ts",
38
+ "import": "./dist/browser.js"
39
+ },
15
40
  "./package.json": "./package.json"
16
41
  },
17
42
  "scripts": {
@@ -19,5 +44,18 @@
19
44
  "test": "node --test tests/*.test.mjs",
20
45
  "pretest": "npm run build",
21
46
  "prepack": "npm run build"
22
- }
47
+ },
48
+ "homepage": "https://wavebird.ai/api/quickstart",
49
+ "bugs": {
50
+ "url": "https://github.com/wavebird-ai/api/issues"
51
+ },
52
+ "keywords": [
53
+ "wavebird",
54
+ "advertising",
55
+ "javascript",
56
+ "typescript",
57
+ "ai-apps",
58
+ "consent",
59
+ "publisher-integration"
60
+ ]
23
61
  }
@@ -0,0 +1,46 @@
1
+ # wavebird Python integration
2
+
3
+ Connect a Python server to wavebird placement, consent and generation reporting. The browser uses the official wavebird renderer. Banner, Native and Clip follow the saved project's formats and timing.
4
+
5
+ This is a separate package from `@wavebirdai/api`. Python and Web have independent versions. Live ads require separate project approval.
6
+
7
+ ## Install
8
+
9
+ Use Python 3.11 or later. Download the wheel from the [0.1.0b9 release](https://github.com/wavebird-ai/api/releases/tag/python-v0.1.0b9). Verify its SHA-256 before installing:
10
+
11
+ ```text
12
+ wavebird_publisher_server-0.1.0b9-py3-none-any.whl
13
+ 86949813a16d895d54958d042833836f02264c7665a884c39b2094ada2538f34
14
+ ```
15
+
16
+ In your app's virtual environment, install the downloaded file:
17
+
18
+ ```sh
19
+ python -m pip install ./wavebird_publisher_server-0.1.0b9-py3-none-any.whl
20
+ ```
21
+
22
+ The server exports are:
23
+
24
+ ```python
25
+ from wavebird_publisher import PublisherConfig, PublisherServer
26
+ ```
27
+
28
+ This import is not a complete configuration. Use the [FastAPI connection guide](examples/fastapi_app/README.md) for session, generation and browser hooks. FastAPI and an ASGI server are separate application dependencies. The wheel is distributed through GitHub Releases, not through this npm package.
29
+
30
+ ## Configure and connect
31
+
32
+ 1. Save the project settings and exact approved origins in [Dashboard](https://dashboard.wavebird.ai/wavebird). Keep the Server Key and Preference Secret on the server.
33
+ 2. Configure `PublisherConfig` from those saved values. Use `server_key`. The older `server_test_key` name remains compatible for existing Test integrations.
34
+ 3. Mount the FastAPI routes in your app and connect its real session validation and abortable model response. Default example hooks deny access or raise until connected.
35
+ 4. Load the same-origin `/api/wavebird/browser.js` module beside a reserved slot. Connect the real response consumer and consent flow. Python alone does not display an ad.
36
+ 5. Check the visible creative, its reporting and Test Logs. Test activity is nonpayable. No-Fill, denied consent or ad failures must leave model generation usable.
37
+
38
+ ## Deployment
39
+
40
+ Use `turn_journal_path` on durable storage shared by workers on one host. The SQLite journal preserves turn bindings and pending generation reports across restarts. The in-memory coordinator remains compatible with older integrations. Multi-host and serverless deployments require a separately verified shared-store path.
41
+
42
+ The supplied FastAPI example enables responsive selection using saved sizes and format mappings. The low-level Python configuration does not enable it by default. Optional width and height caps can only narrow the saved envelope.
43
+
44
+ Each enabled format needs a visible integration check. Clip also needs playback and natural-end cleanup checks.
45
+
46
+ [API docs](https://wavebird.ai/api/quickstart) | [Integration paths](https://wavebird.ai/api/integration-paths) | [Troubleshooting](https://wavebird.ai/api/troubleshooting)
@@ -0,0 +1,42 @@
1
+ # Connect an existing FastAPI app
2
+
3
+ Install the [Python 0.1.0b9 wheel](../../README.md#install), FastAPI and your ASGI server in the app's environment. The example uses the package's existing `/v1` contract and keeps credentials server-side.
4
+
5
+ ## 1. Set server configuration
6
+
7
+ `run.py` reads the following values. Copy the saved project settings rather than choosing new formats or origins in the browser.
8
+
9
+ | Purpose | Environment variables |
10
+ | --- | --- |
11
+ | Project and secrets | `WAVEBIRD_CLIENT_ID`, `WAVEBIRD_SECRET_KEY`, `WAVEBIRD_PREFERENCE_SECRET` |
12
+ | Origins | `WAVEBIRD_PUBLIC_ORIGINS` |
13
+ | Placement | `WAVEBIRD_SURFACE_ID`, `WAVEBIRD_PLACEMENT_KEY`, `WAVEBIRD_JOB_TYPE`, `WAVEBIRD_POSITION_HINT` |
14
+ | Consent and timing | `WAVEBIRD_CONSENT_MODE`, `WAVEBIRD_GDPR_APPLIES`, `WAVEBIRD_TIMING` |
15
+ | Publisher | `WAVEBIRD_APP_NAME`, `WAVEBIRD_APP_DOMAIN`, `WAVEBIRD_LOCALE` |
16
+ | Formats and sizes | `WAVEBIRD_ALLOWED_FORMATS`, `WAVEBIRD_ALLOWED_SIZES`, `WAVEBIRD_SIZE_FORMATS_JSON` |
17
+ | Turn storage | `WAVEBIRD_TURN_JOURNAL_PATH` |
18
+
19
+ Origins are comma-separated exact origins, including scheme and port. `www` and the bare domain are separate entries. Sizes use `320x50,300x250` syntax. A format map such as `[[320,50,["banner"]],[300,250,["native","clip"]]]` must cover every saved size with its actual allowed formats. These are syntax examples, not replacement project values.
20
+
21
+ The journal path must be absolute and durable, shared by the app's workers on one host. Keep secrets out of Git, responses and browser bundles.
22
+
23
+ ## 2. Connect session and generation
24
+
25
+ In `publisher_hooks.py`:
26
+
27
+ - `session_id_for_request` returns the server-validated app session ID. Authorization derives from that hook. Its default denies access.
28
+ - `existing_generation` calls your existing model stream and preserves response and cancellation. Its default raises an error.
29
+
30
+ The example's `create_app(..., host_app=your_existing_app, turn_journal_path=...)` mounts package routes without replacing your routes or middleware. It uses `mount_fastapi` from the installed package. Do not call the example factory as though it were a package export.
31
+
32
+ ## 3. Connect the browser
33
+
34
+ Load the package's same-origin `/api/wavebird/browser.js` module beside your reserved slot. Supply real session and model-response hooks, saved timing, job type, slot settings and consent mode. Resolve the consumer only after presenting the result. Dispose the browser integration on sign-out and teardown.
35
+
36
+ For an app mounted at `/app`, load the module under that mount and pass `apiBasePath: "/app"`. This accepts local path segments, not another origin. The module loads the official `https://api.wavebird.ai/v1/render.js` renderer.
37
+
38
+ ## 4. Verify
39
+
40
+ Check the visible creative, reporting and a durable nonpayable project fact. Clip additionally needs playback and completion. Check No-Fill, refusal, withdrawal and Stop while confirming the model still works.
41
+
42
+ Local adapter tests cover routing and security controls. They do not replace visible browser checks. This SQLite path does not qualify a multi-host or serverless deployment.