Feature: My Jobs - EyevinnOSC/community GitHub Wiki

My Jobs

My Jobs is a feature in OSC that lets you create and schedule background Python jobs that run on a cron schedule. Instead of managing your own infrastructure, OSC provisions an ephemeral job runner for each execution and cleans it up automatically when the job completes.

What You Can Do

  • Create scheduled background jobs from a Git repository (including private OSC Gitea repos)
  • Set any cron expression as the schedule
  • Trigger a job immediately with a single API call
  • Suspend a job without deleting it, and resume it later
  • Bind a parameter store to a job so its contents are injected as environment variables at runtime
  • Review the run history of a job and read the logs of each run
  • Clone private GitHub, GitLab or Gitea repositories by referencing a stored Git Credential by name

Prerequisites

  • An OSC account on a paid plan (Personal, Professional, or Business)
  • A Personal Access Token (PAT) for authentication — create one on the API Access page (see Finding Your API Token)
  • A Python job in a Git repository (public or OSC Gitea)

Using the Web Console

My Jobs is accessible from the top-level Jobs tab in the My Apps section:

  1. Navigate to My Apps in the OSC dashboard
  2. Click the Jobs tab (alongside the Apps tab)
  3. All scheduled jobs across your workspace are listed here, regardless of which app they belong to
  4. Click Create job to add a new scheduled job. The create form includes a Parameter store selector (optional) — choose an existing parameter store instance to inject its values as environment variables when the job runs. Use the action buttons to run, suspend, or delete an existing job.
  5. Click the View runs icon (or the Last run status chip) on a job to open its run history. Each run shows its status and whether it was started by the schedule or manually. Open a run to read its logs.
  6. To modify an existing job, click the pencil icon next to it. The edit modal lets you update the cron schedule, source URL, worker command, and parameter store binding without deleting and recreating the job.
  7. Both the create and edit dialogs have an optional Git credential selector. Pick a stored Git Credential to let the job clone a private GitHub, GitLab or Gitea repository. Choose None to clear it. If you have no credentials yet, the dialog links to the page where you can add one. If the selected credential has been deleted, the selector says so and you can choose another. The credential is ignored for OSC-hosted Gitea repositories.

How It Works

When a scheduled job is due, deploy-manager spins up an ephemeral eyevinn-python-job-runner instance, passes your source URL and worker command, and tears it down after execution. Credentials for private OSC Gitea repositories are resolved at trigger time — they are never stored in the job definition.

Using MCP Tools

AI assistants connected to the OSC MCP server can manage the git credential of a job:

  • create-my-job accepts an optional gitCredential argument with the friendly name of a registered Git Credential. If no credential with that name exists, the tool returns an error and nothing is created.
  • update-my-job sets, changes or clears the git credential of an existing job. Pass gitCredential to set or change it, or clearGitCredential to remove it (pass one of the two, not both).
  • list-my-jobs and get-my-job show the credential name as Git Credential.
  • list-git-credentials lists the credential names you can use.

API Reference

All endpoints require a PAT passed as Authorization: Bearer <pat> in the x-pat-jwt header.

Base URL: https://deploy.svc.prod.osaas.io

List jobs

curl -s -H "x-pat-jwt: Bearer $PAT" \
  https://deploy.svc.prod.osaas.io/myjobs

Create a job

curl -s -X POST \
  -H "x-pat-jwt: Bearer $PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "dailysync",
    "cronSchedule": "0 9 * * 1-5",
    "sourceUrl": "https://github.com/myorg/myrepo",
    "workerCmd": "python jobs/sync.py",
    "configService": "my-param-store"
  }' \
  https://deploy.svc.prod.osaas.io/myjobs
Field Required Description
name Yes Alphanumeric identifier (no hyphens or underscores)
cronSchedule Yes Standard 5-field cron expression (e.g. 0 9 * * 1-5)
sourceUrl Yes URL of the Git repository containing your Python script
workerCmd No Command to run (defaults to the runner's built-in entrypoint)
configService No Name of a Parameter Store service instance whose values are injected as environment variables at runtime
configApiKey No API key for the parameter store. Required only if the store was set up with encryption (encrypted secrets); leave blank for plain parameter stores
gitCredentialRef No Name of a stored Git Credential used to clone a private repository. Only the name is stored; the token is resolved each time the job runs. Returns 404 if no credential with that name exists. Send null on update to clear it

Get a job

curl -s -H "x-pat-jwt: Bearer $PAT" \
  https://deploy.svc.prod.osaas.io/myjobs/dailysync

Update a job

curl -s -X PATCH \
  -H "x-pat-jwt: Bearer $PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "cronSchedule": "0 8 * * 1-5",
    "sourceUrl": "https://github.com/myorg/new-repo",
    "workerCmd": "python jobs/new_entry.py",
    "configService": "my-param-store",
    "configApiKey": "new-key"
  }' \
  https://deploy.svc.prod.osaas.io/myjobs/dailysync

Only the fields you include in the body are changed. Send "configService": null or "configApiKey": null to clear those fields. Omit a field entirely to leave it unchanged.

Trigger an immediate run

curl -s -X POST \
  -H "x-pat-jwt: Bearer $PAT" \
  https://deploy.svc.prod.osaas.io/myjobs/dailysync/run

The response is returned immediately (HTTP 201) once the job runner is started. OSC polls the runner in the background and updates lastRunStatus to success or failed once the job completes — the same behavior as a scheduled run. Poll GET /myjobs/dailysync to check the outcome.

List run history

curl -s -H "x-pat-jwt: Bearer $PAT" \
  "https://deploy.svc.prod.osaas.io/myjobs/dailysync/runs?limit=20&offset=0"

Runs are returned newest first, for both scheduled and manual runs. limit is 1 to 100 (default 20) and offset starts at 0. The X-Total-Count response header holds the total number of runs. A run that is still in progress is refreshed with its current status when you list it. Jobs that ran before run history was introduced show a single entry for their last run.

Get the logs of a run

curl -s -H "x-pat-jwt: Bearer $PAT" \
  "https://deploy.svc.prod.osaas.io/myjobs/dailysync/runs/$RUN_ID/logs"

Secrets, bearer tokens and credentials embedded in URLs are redacted from the log text. Run logs are kept for 7 days after a run ends, including runs whose pod has already been removed. After 7 days the response has logsAvailable: false. Use the optional cursor query parameter (a line offset) to read from a given line.

Suspend a job (disable without deleting)

curl -s -X POST \
  -H "x-pat-jwt: Bearer $PAT" \
  https://deploy.svc.prod.osaas.io/myjobs/dailysync/suspend

Resume a suspended job

curl -s -X POST \
  -H "x-pat-jwt: Bearer $PAT" \
  https://deploy.svc.prod.osaas.io/myjobs/dailysync/resume

Delete a job

curl -s -X DELETE \
  -H "x-pat-jwt: Bearer $PAT" \
  https://deploy.svc.prod.osaas.io/myjobs/dailysync

Job Response Fields

Field Type Description
name string Job name
tenantId string Your workspace ID
runtime string The job runtime (e.g. python-job)
cronSchedule string The cron expression
sourceUrl string Git repository URL
workerCmd string Worker command (if set)
configService string Name of the bound parameter store instance (if set)
gitCredentialRef string Name of the Git Credential used to clone the repository (if set)
enabled boolean Whether the job is active
lastRunAt number Unix timestamp of the last run (or null)
lastRunStatus string Status of the last run (or null)
createdAt string ISO 8601 creation timestamp
updatedAt string ISO 8601 last-update timestamp

Resources

⚠️ **GitHub.com Fallback** ⚠️