# App: Sources

**Page:** api/app/sources

[Download Raw Markdown](./api/app/sources.md)

---

{/* AUTO-GENERATED — Do not edit manually. Regenerate with: npm run docs:api:generate */}



The Sources API lets you manage the package sources Hoody uses to resolve application candidates. Use these endpoints to list, create, update, delete, sync, and diagnose individual sources. Sources can be providers like `nix`, `pkgx`, `appimage`, `oci`, `registry`, or `system`, and each source has a specific implementation type that determines how it resolves and syncs candidates.

## List sources

### `GET /api/v1/run/sources`

List all configured package sources with their type, provider, priority, enabled state, and provider-specific configuration.

This endpoint takes no parameters.



```bash
curl -X GET https://api.hoody.com/api/v1/run/sources \
  -H "Authorization: Bearer &lt;token&gt;"
```


```typescript
const sources = await client.app.sources.list();
```



#### Response — 200

Array of source configurations.

```json
[
  {
    "source_id": "nixpkgs",
    "enabled": true,
    "priority": 100,
    "provider": "nix",
    "source_type": "nix-flake",
    "pin": {
      "url": "https://github.com/NixOS/nixpkgs"
    },
    "config": {
      "flake": "nixpkgs"
    }
  },
  {
    "source_id": "pkgx-default",
    "enabled": true,
    "priority": 80,
    "provider": "pkgx",
    "source_type": "pkgx"
  }
]
```

## Get source diagnostics

### `GET /api/v1/run/sources/{source_id}/diagnostics`

Return runtime-only health and observability data for a configured source, including recent search or sync failures.

### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `source_id` | path | string | Yes | Source identifier |

This endpoint accepts no request body.



```bash
curl -X GET https://api.hoody.com/api/v1/run/sources/nixpkgs/diagnostics \
  -H "Authorization: Bearer &lt;token&gt;"
```


```typescript
const diagnostics = await client.app.sources.getDiagnostics({
  source_id: "nixpkgs"
});
```



#### Response — 200

```json
{
  "source_id": "nixpkgs",
  "status": "ok",
  "last_success_at": "2025-01-15T10:30:00Z",
  "last_error_at": null,
  "last_error": null,
  "last_search_latency_ms": 142,
  "last_sync_job_id": "550e8400-e29b-41d4-a716-446655440000",
  "cache_hint": "warm",
  "effective_enabled_reason": "configured and enabled",
  "provider_details": {
    "flake_rev": "abc123def456"
  }
}
```

#### Response — 404

Source not found.

```json
{
  "error": "Source not found",
  "code": 404
}
```

## Create a source

### `POST /api/v1/run/sources`

Add a new package source configuration. The source will be appended to the existing list and immediately available for searches if enabled.

This endpoint takes no parameters.

### Request Body

Source configuration object.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `source_id` | string | Yes | Unique source identifier (e.g. `nixpkgs`) |
| `enabled` | boolean | Yes | Whether this source is active for searches |
| `priority` | integer | Yes | Source priority (higher values are searched first and ranked higher) |
| `provider` | string | Yes | Package source provider kind. One of: `nix`, `pkgx`, `appimage`, `oci`, `registry`, `system`, `any` |
| `source_type` | string | Yes | Specific source implementation type. One of: `nix-pkgs`, `nix-flake`, `pkgx`, `app-image-pinned`, `app-image-git-hub-releases`, `app-image-catalog`, `oci-local-images`, `manifest-registry`, `manifest-remote-index`, `system-path`, `trusted-list-file` |
| `pin` | object | No | Pin configuration (URL plus optional integrity fields) |
| `config` | object | No | Provider-specific configuration (varies by `source_type`) |

The `pin` object accepts the following fields:

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `url` | string | Yes | Pinned URL for the source |
| `sha256` | string | No | SHA-256 hash for integrity verification |
| `author_pubkey_ed25519` | string | No | Ed25519 public key of the source author (base64) |
| `sig_ed25519` | string | No | Ed25519 signature for provenance verification (base64) |



```bash
curl -X POST https://api.hoody.com/api/v1/run/sources \
  -H "Authorization: Bearer &lt;token&gt;" \
  -H "Content-Type: application/json" \
  -d '{
    "source_id": "nixpkgs",
    "enabled": true,
    "priority": 100,
    "provider": "nix",
    "source_type": "nix-flake",
    "pin": {
      "url": "https://github.com/NixOS/nixpkgs"
    },
    "config": {
      "flake": "nixpkgs"
    }
  }'
```


```typescript
const sources = await client.app.sources.create({
  source_id: "nixpkgs",
  enabled: true,
  priority: 100,
  provider: "nix",
  source_type: "nix-flake",
  pin: {
    url: "https://github.com/NixOS/nixpkgs"
  },
  config: {
    flake: "nixpkgs"
  }
});
```



#### Response — 200

Updated list of all sources.

```json
[
  {
    "source_id": "nixpkgs",
    "enabled": true,
    "priority": 100,
    "provider": "nix",
    "source_type": "nix-flake",
    "pin": {
      "url": "https://github.com/NixOS/nixpkgs"
    },
    "config": {
      "flake": "nixpkgs"
    }
  }
]
```

#### Response — 400

Missing source_id.

```json
{
  "error": "Missing source identifier",
  "code": 400
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `MISSING_SOURCE_ID` | Missing source identifier | The source configuration did not include a non-empty `source_id` | Set `source_id` before creating the source |

#### Response — 409

Source already exists.

```json
{
  "error": "Source already exists",
  "code": 409
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `SOURCE_ALREADY_EXISTS` | Source already exists | A source with the same `source_id` already exists | Choose a unique `source_id` or update the existing source instead |

#### Response — 503

Configuration persistence failed.

```json
{
  "error": "Configuration save failed",
  "code": 503
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `CONFIG_SAVE_FAILED` | Configuration save failed | The updated source configuration could not be persisted | Check storage health and retry |

## Sync sources

### `POST /api/v1/run/sources/{source_id}/sync`

Trigger a sync operation for a specific source. Returns immediately with a job handle for tracking progress via the jobs endpoint.

### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `source_id` | path | string | Yes | Source identifier |

This endpoint accepts no request body.



```bash
curl -X POST https://api.hoody.com/api/v1/run/sources/nixpkgs/sync \
  -H "Authorization: Bearer &lt;token&gt;"
```


```typescript
const job = await client.app.sources.sync({
  source_id: "nixpkgs"
});
```



#### Response — 202

Sync job accepted.

```json
{
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "kind": "source-sync",
  "status": "running",
  "created_at": "2025-01-15T10:30:00Z",
  "updated_at": "2025-01-15T10:30:05Z"
}
```

#### Response — 503

Sync could not be started.

```json
{
  "error": "Sync start failed",
  "code": 503
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `SYNC_START_FAILED` | Sync start failed | The source sync job could not be started | Retry or inspect source/provider health |

### `POST /api/v1/run/sources/sync`

Trigger a sync operation for all enabled sources. Returns immediately with a job handle. Use `GET /api/v1/run/jobs/{job_id}?wait=done&timeout_ms=30000` to poll for completion.

This endpoint takes no parameters.

This endpoint accepts no request body.



```bash
curl -X POST https://api.hoody.com/api/v1/run/sources/sync \
  -H "Authorization: Bearer &lt;token&gt;"
```


```typescript
const job = await client.app.sources.syncAll();
```



#### Response — 202

Sync job accepted.

```json
{
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "kind": "source-sync",
  "status": "running",
  "created_at": "2025-01-15T10:30:00Z",
  "updated_at": "2025-01-15T10:30:05Z"
}
```

#### Response — 503

Sync could not be started.

```json
{
  "error": "Sync start failed",
  "code": 503
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `SYNC_START_FAILED` | Sync start failed | The all-sources sync job could not be started | Retry or inspect source/provider health |

## Update a source

### `PATCH /api/v1/run/sources/{source_id}`

Partially update a source configuration. Supports merging `enabled`, `priority`, `pin`, and `config` fields.

### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `source_id` | path | string | Yes | Source identifier |

### Request Body

The body is an open-ended partial source configuration object. Any fields provided are merged into the existing configuration. Common fields include `enabled`, `priority`, `pin`, and `config`.



```bash
curl -X PATCH https://api.hoody.com/api/v1/run/sources/nixpkgs \
  -H "Authorization: Bearer &lt;token&gt;" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled": true,
    "priority": 150
  }'
```


```typescript
const source = await client.app.sources.update({
  source_id: "nixpkgs",
  data: {
    enabled: true,
    priority: 150
  }
});
```



#### Response — 200

Updated source configuration.

```json
{
  "source_id": "nixpkgs",
  "enabled": true,
  "priority": 150,
  "provider": "nix",
  "source_type": "nix-flake"
}
```

#### Response — 404

Source not found.

```json
{
  "error": "Source not found",
  "code": 404
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `SOURCE_NOT_FOUND` | Source not found | No source exists with the requested `source_id` | Call `list()` and choose a valid `source_id` |

#### Response — 503

Configuration persistence failed.

```json
{
  "error": "Configuration save failed",
  "code": 503
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `CONFIG_SAVE_FAILED` | Configuration save failed | The updated source configuration could not be persisted | Check storage health and retry |

## Delete a source

### `DELETE /api/v1/run/sources/{source_id}`

Remove a package source by its ID. Returns 204 on success.

### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `source_id` | path | string | Yes | Source identifier |

This endpoint accepts no request body.



```bash
curl -X DELETE https://api.hoody.com/api/v1/run/sources/nixpkgs \
  -H "Authorization: Bearer &lt;token&gt;"
```


```typescript
await client.app.sources.delete({
  source_id: "nixpkgs"
});
```



#### Response — 204

Source deleted successfully. No content returned.

#### Response — 404

Source not found.

```json
{
  "error": "Source not found",
  "code": 404
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `SOURCE_NOT_FOUND` | Source not found | No source exists with the requested `source_id` | Call `list()` and choose a valid `source_id` |

#### Response — 503

Configuration persistence failed.

```json
{
  "error": "Configuration save failed",
  "code": 503
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `CONFIG_SAVE_FAILED` | Configuration save failed | The updated source configuration could not be persisted | Check storage health and retry |