> ## Documentation Index
>
> Fetch the complete documentation index at: https://lithi.ai/llms.txt
>
> Use this file to discover all available pages before exploring further.

---
title: Use the Swift client
description: >-
  How the released Swift client is shaped, and why it is a different product from the
  separate application people install to help power approved network tasks.
route: /docs/compute/clients/swift
page_id: docs-compute-clients-swift
page_type: howTo
content_layer: guided documentation
surface_profile: guided_docs
audience: Swift developers submitting Compute work from an app or service
voice: D
reader_question: How do I call Compute from Swift, and is this the same as the provider app?
primary_action: Check your client version against the compatibility matrix
source_locale: en-US
source_status: APPROVED
source_version: docs-compute-clients-swift-en-us-2026-09-05-v1
last_updated: '2026-09-05'
robots: index
claim_registry_pinned: true
claim_registry_resync: "npm run governed:tsx -- scripts/build-compute-public-claim-registry.ts --write"
---

## Package and platform requirements

This page prints no package name and no minimum platform version. Both move with each release, so both are published on the compatibility matrix instead.

Read your row there before you add the dependency. It names the released package, its version, the platforms tested against it, and the protocol release it speaks.

Your base URL and current API version appear in the portal under developer settings, and in the API description you download.

## This client is not the provider application

Two Lithi products get confused here, so keep them apart.

This client is for customers. It submits work, reads status, and downloads results, and it is the only one of the two you need to use Compute.

The separate application people install to help power approved network tasks is a different product, with a different audience and a different setup. Installing it changes nothing about what your account can submit, and not installing it costs you nothing.

How accepted work is actually carried out is not something any client configures or exposes. You describe the outcome you want, and you approve a price for it.

## Submit work

The client mirrors the API namespaces, so a call site shows the authority it needs.

```swift
let quote = try await client.work.quote(taskSpec)
// A quote is non-authorizing. It carries an expiry and a signature.

try await approve(quote)
let job = try await client.work.run(quote)
```

Your `taskSpec` carries the same seven objects everywhere: `workflow`, `input`, `parameters`, `quality`, `policy`, `output` and `limits`.

Approval is always a separate act. Requesting a quote never starts work, and no client can collapse the two steps.

## Await a terminal state

Terminal states are `SUCCEEDED`, `PARTIAL`, `FAILED` and `CANCELLED`. Everything else means keep waiting.

```swift
let status = try await client.work.status(jobID: job.id)

switch status.state {
case .succeeded, .partial:  return try await readResult(job.id)
case .failed, .cancelled:   return report(status.nextAction)
default:                    return try await poll(until: status.validUntil)
}
```

Take the exact type names from your release. Poll on the `validUntil` the response carries, not on an interval you chose.

## Handle refusals and verify the result

Every operation carries its own generated `error_schema`, and every refusal carries a safe reason with a non-empty next action. Keep `EDGE_ABUSE_LIMITED`, `CANONICAL_ADMISSION_LIMITED`, `CANONICAL_BUDGET_EXHAUSTED` and `CELL_CAPACITY_UNAVAILABLE` in separate branches.

Read `result-manifest.json` before any part file. It is written last, and it is the only complete-bundle marker.

Then check the digests in `provenance.json` against what you submitted, and keep `receipt.json` with your own record. Read [your row on the compatibility matrix](/docs/compute/clients/compatibility) and [how to download and verify a result](/docs/compute/results/download-and-verify).
