---
topic: embarko-json
connector: "deploy_app: embarko.json is one of the files"
api: "POST https://ship.embarko.ai/apps (the file travels in the upload)"
requires: [deploy]
---

[← Guide home](https://embarko.ai/docs)

# The embarko.json file

**On this page:** Steps, Examples, Limits, Errors

> Plain words unless the person is a developer. Never invent a link, name or code. [Rules](https://embarko.ai/docs/prerequisites) Needs first: [deploy](https://embarko.ai/docs/deploy).

embarko.json is an optional file in the app's top folder, next to package.json. Embarko reads it on every deploy. It holds three settings: appId, which app this code deploys to; schedules, the timed calls into the app; and lock, which makes the app private.

**Connector:** deploy_app: embarko.json is one of the files

**Done when:** The deploy reply has no embarko.json error or warning, its app.id matches "appId", and its schedules facts match the file.

**Steps**

1. Create embarko.json in the app's top folder, next to package.json (or requirements.txt, go.mod...).
2. Write one JSON object. Put the settings in it: "appId" (app.id from the first deploy reply) and, if the app needs them, "schedules" (see schedules) and/or "lock" (see lock).
3. Optional: add "$schema": "https://embarko.ai/schema/embarko.json" so editors can check it.
4. Deploy as usual: skill, HTTP .tar.gz, JSON files list or connector. The file goes with the other files; there is no special field.
5. Read the reply. A 400 names what is wrong; fix the file and deploy again. Read warnings[] and fix those too before telling the person it is done.

**Example: embarko.json with one schedule**

```json
{
  "$schema": "https://embarko.ai/schema/embarko.json",
  "appId": "cmh1q2w3e0001abcdmyapp",
  "schedules": [
    {
      "cron": "0 9 * * 1-5",
      "path": "/tasks/daily-digest",
      "timezone": "Asia/Kolkata",
      "name": "daily digest"
    }
  ]
}
```

"appId", "schedules" and "lock" are the only settings. Fields of a schedule: see schedules. Add "lock": true to make the app private: see lock.

**Limits**

- Optional. No file means no change.
- "appId" decides which app the deploy goes to, so a deploy under the app's old name still reaches it after a rename. Keep it after the first deploy and commit it. A deploy with an "appId" never creates a new app: one the token cannot reach gets 404 app_not_found, a deleted one 410 app_deleted, a moved one 409 app_moved.
- Copying an app's code to start a new app copies its "appId" too. Remove it before the first deploy of the copy: a name the app never had gets 409 app_id_mismatch, so the original app is never overwritten.
- "appId" is read for token deploys only. A dashboard upload goes to the app the person picked.
- The file is the source of truth. A setting changed through the API is set back by the next deploy whose file lists it.
- "schedules" is the app's full set, matched by path. [] removes all. A file without a "schedules" key leaves them as they are.
- "lock" is true or false. A file without a "lock" key leaves the lock as it is, so a redeploy never unlocks an app. The password, if any, is set in the dashboard only.
- Never put secrets in it. It is part of the code and is never private. Use env vars (see env-vars).
- Only the top folder is read. A copy in a subfolder is ignored.
- Only the exact name embarko.json is read. Not .embarko, embarko.yaml, embarko.config.json or embarko.jsonc.
- Plain JSON: no comments, no trailing commas.
- Unknown keys are ignored, with a warning.
- At most 64 KB.

**Errors**

| Code | Status | Retry | What to do |
| --- | --- | --- | --- |
| `invalid_embarko_json` | 400 | No | Not valid JSON (the message gives line and column), not one object, "schedules" is not a list, "appId" is not an id, "lock" is not true/false, or over 64 KB. Fix the file and deploy again. |
| `app_not_found / app_deleted` | 404 / 410 | No | "appId" leads to no app in this workspace, or to a deleted one. Check the token. To deploy as a new app, ask the person, then remove "appId". |
| `app_id_mismatch` | 409 | No | "appId" is another app's, and the name you sent was never its name: this code was likely copied. For a new app, remove "appId". To update that app, deploy under its name. |
| `secrets_in_embarko_json` | 400 | No | A key named like secret, token, password, api key, private key or credential, or a value that looks like a key or a URL with ?token=. Remove it and set it as an env var. |
| `invalid_schedules / invalid_cron / schedule_too_frequent / invalid_timezone / invalid_path / duplicate_schedule_path / schedule_limit_reached` | 400 | No | A schedule entry is wrong. The message names it, e.g. "Schedule 1: ...". Fixes: see schedules. |
| `embarko_json_not_at_top (warning)` | 202 | No | Found in a subfolder; only the top folder is read. Move it next to package.json and deploy again. |
| `embarko_json_misnamed (warning)` | 202 | No | A file like .embarko or embarko.yaml was found. Rename it to embarko.json, as JSON, and deploy again. |
| `embarko_json_unknown_keys (warning)` | 202 | No | Keys Embarko does not use were ignored. Remove them, or check the spelling of "schedules" and "lock". |
| `lock_ignored_orphan (warning)` | 202 | No | The app is temporary, so "lock" was not applied. Claim it, then deploy again with the same file. |
| `in_process_timer (warning)` | 202 | No | The code uses a timer library (node-cron, APScheduler...) and the file lists no schedules. Move each job into a route and list it under "schedules". |
| `schedules_unchanged (warning)` | 202 | No | The app has schedules and this upload declares none, so they were kept. To remove them, deploy with "schedules": []. |
| `schedules_on_static_site (warning)` | 202 | No | A static site runs no code, so its schedules were not applied. Deploy it as a server app to use them. |

**Next:** After the first deploy, save app.id as "appId" in embarko.json. Add schedules or lock only if the app needs them. Deploy and read the reply's warnings.

**Related:** [schedules](https://embarko.ai/docs/schedules) · [lock](https://embarko.ai/docs/lock) · [rename](https://embarko.ai/docs/rename) · [env-vars](https://embarko.ai/docs/env-vars) · [errors](https://embarko.ai/docs/errors)

---

[Guide home](https://embarko.ai/docs) · JSON: add .json