# \[HOW-TO\]\[Pro\] Generate notification text with an OpenAI-compatible LLM endpoint (hosted or local) from HomeyScript

**URL:** <https://community.homey.app/t/how-to-pro-generate-notification-text-with-an-openai-compatible-llm-endpoint-hosted-or-local-from-homeyscript/161039>\
**Category:** Tutorials\
**Created:** [October 18, 2026, 3:04pm UTC](https://community.homey.app/t/how-to-pro-generate-notification-text-with-an-openai-compatible-llm-endpoint-hosted-or-local-from-homeyscript/161039 "2026-10-18T15:04:45Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![apigoto](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/apigoto/32/179639_2.png) [@apigoto](https://community.homey.app/u/apigoto)\
**Post date:** [October 18, 2026, 3:04pm UTC](https://community.homey.app/t/how-to-pro-generate-notification-text-with-an-openai-compatible-llm-endpoint-hosted-or-local-from-homeyscript/161039/1 "2026-10-18T15:04:45Z")

</div>

I work on the APIGOTO team. APIGOTO is an independent OpenAI-compatible gateway, not affiliated with OpenAI, Anthropic or Google. This builds on the “[HOW TO] use a local LLM to generate unique notifications” tutorial. The same script works against a local server or any hosted OpenAI-compatible endpoint, because only the base URL and model ID change.

**What you need**

- Homey Pro (HomeyScript runs locally only).
- The HomeyScript app, scripts at [My Homey](https://my.homey.app/scripts)
- An API key, and a model ID taken from `GET <base URL>/models`

**1. Test the endpoint outside Homey**

```bash
curl https://api.china-aiapi.com/v1/chat/completions \
  -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
  -d '{"model":"MODEL_ID","messages":[{"role":"user","content":"Say hi"}]}'

```

**2. Store the key once**

Create a script called `set-llm-key`, run it once, then delete the key from the code:

```js
global.set('llm_api_key', 'PASTE_KEY_HERE');
log('saved');

```

**3. The script that calls the model**

Create a script called `llm-notify`:

```js
const BASE_URL = 'https://api.china-aiapi.com/v1'; // or http://<lan-ip>:<port>/v1 for a local server
const MODEL = 'MODEL_ID';

const key = global.get('llm_api_key');
const facts = args[0] || 'The front door was opened.';

const res = await fetch(`${BASE_URL}/chat/completions`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${key}` },
  body: JSON.stringify({
    model: MODEL,
    max_tokens: 80,
    messages: [
      { role: 'system', content: 'Write one short, friendly smart-home notification. No emojis, max 20 words.' },
      { role: 'user', content: facts },
    ],
  }),
  timeout: 20000, // node-fetch v2 option, in ms
});

if (!res.ok) {
  log('HTTP', res.status, (await res.text()).slice(0, 300));
  return facts; // fall back to the plain text so the Flow still notifies
}

const data = await res.json();
return (data.choices?.[0]?.message?.content || facts).trim();

```

**4. The Flow**

- **When** : whatever event you want (door opened, washer finished…).
- **Then** : HomeyScript → _Run [code] with [argument] and return Text-tag_. Pick `llm-notify`. As the argument, write the facts with tags, for example `Washer finished. Outside temperature: [tag] °C`.
- **Then** : _Send a push notification_ (or a speaker “say” card) with the **Result** tag from the card above.

The script returns the original facts on any error, so a dead endpoint never means a missing notification.

**Troubleshooting**

- Nothing in the Result tag: open the script editor and run it with a test argument. `log()` output shows the HTTP status.
- HTTP 401: the key wasn’t saved (run `set-llm-key` again) or has a trailing space.
- HTTP 404: `/v1` missing or doubled in `BASE_URL`.
- “model not found”: `MODEL` doesn’t match `/models` exactly.
- The script stops early: HomeyScript has a run timeout, so keep `timeout` short and `max_tokens` low. Notifications don’t need long answers.
- Privacy: whatever you put in the argument (names, presence, temperatures) goes to the endpoint. A local server keeps it on your LAN.

On the gateway side: one base URL for several model families, automatic failover on upstream errors (at most 3 retries per request on another route), a per-request log, pay-as-you-go, BYOK: [www.china-aiapi.com](https://www.china-aiapi.com/grokbot)

Which events do you actually want “unique” wording for, and which do you keep fixed?
