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

# Swift SDK

> Official CoinPaprika API Swift client library

# CoinPaprika Swift SDK

The official Swift client library for the CoinPaprika API provides convenient, static access to cryptocurrency market data.

## Installation

### Swift Package Manager (SPM)

Add the following package dependency to your `Package.swift` file or via Xcode:

```
https://github.com/coinpaprika/coinpaprika-api-swift-client
```

### CocoaPods

Add the following line to your Podfile and run `pod install`:

```ruby theme={"dark"}
pod 'CoinpaprikaAPI'
```

## Quick Start

First, import the library:

```swift theme={"dark"}
import Coinpaprika
```

Then, you can call any API endpoint via the static `Coinpaprika.API` object. All requests are asynchronous and return a `Result` type in a closure.

```swift theme={"dark"}
// Get global market stats
Coinpaprika.API.global().perform { result in
    switch result {
    case .success(let stats):
        print("Market Cap: $\(stats.marketCapUsd)")
        print("24h Volume: $\(stats.volume24hUsd)")
        print("Bitcoin Dominance: \(stats.bitcoinDominancePercentage)%")
    case .failure(let error):
        print("An error occurred: \(error)")
    }
}
```

## Authenticating with a paid plan

Paid plans (Starter / Pro / Business / Ultimate / Enterprise) live on a separate hostname, `https://api-pro.coinpaprika.com/v1/`, and require an API key in the `Authorization` header. Send the bare key — a `Bearer ` prefix is rejected by the WAF.

The high-level `Coinpaprika.API` static methods don't currently accept a key. To call paid endpoints, drop down to the `CoinpaprikaNetworking` `Request<Model>` constructor with `.bearer(token:)` and point it at the Pro base URL. The package exposes `CoinpaprikaNetworking` as a separate library product, so add it to your target's dependencies alongside `Coinpaprika`.

```swift theme={"dark"}
import CoinpaprikaNetworking
import Foundation

struct KeyInfo: Codable {
    let plan: String
    let plan_status: String
}

let key = ProcessInfo.processInfo.environment["COINPAPRIKA_API_KEY"]!

let request = Request<KeyInfo>(
    baseUrl: URL(string: "https://api-pro.coinpaprika.com/v1/")!,
    method: .get,
    path: "key/info",
    params: nil,
    userAgent: "my-app/1.0",
    authorisation: .bearer(token: key)
)

request.perform { result in
    switch result {
    case .success(let info):
        print("Plan: \(info.plan), status: \(info.plan_status)")
    case .failure(let error):
        print("Error: \(error)")
    }
}
```

For free-tier endpoints that don't need a key (most of `Coinpaprika.API`), keep using the high-level static API against the default base URL.

## Common Use Cases

### Ticker Data for a Specific Coin

```swift theme={"dark"}
import Coinpaprika

Coinpaprika.API.ticker(id: "btc-bitcoin", quotes: [.usd, .btc]).perform { response in
    switch response {
    case .success(let ticker):
        print("Bitcoin Information:")
        print("Name: \(ticker.name)")
        print("Symbol: \(ticker.symbol)")
        
        // Access quotes using subscripting
        if let usdQuote = ticker[.usd] {
            print("USD Price: $\(usdQuote.price)")
            print("Market Cap: $\(usdQuote.marketCap)")
        }
        
        if let btcQuote = ticker[.btc] {
            print("BTC Price: ₿\(btcQuote.price)")
        }
    case .failure(let error):
        print("Error: \(error)")
    }
}
```

### Coin Details

```swift theme={"dark"}
import Coinpaprika

Coinpaprika.API.coin(id: "eth-ethereum").perform { response in
    switch response {
    case .success(let coin):
        print("Ethereum Details:")
        print("Name: \(coin.name)")
        print("Description: \(coin.description ?? "N/A")")
        print("Development Status: \(coin.developmentStatus)")
    case .failure(let error):
        print("Error: \(error)")
    }
}
```

### Historical Ticker Data

Historical endpoints require a paid plan. The high-level `Coinpaprika.API.historicalTicks(...)` shape is shown below for the request structure; to actually authenticate, build a `Request<Tick>` against the Pro base URL using the `.bearer(token:)` pattern from "Authenticating with a paid plan".

```swift theme={"dark"}
import CoinpaprikaNetworking
import Foundation

struct Tick: Codable {
    let timestamp: String
    let price: Double
    let volume24h: Double
    enum CodingKeys: String, CodingKey {
        case timestamp, price
        case volume24h = "volume_24h"
    }
}

let key = ProcessInfo.processInfo.environment["COINPAPRIKA_API_KEY"]!
let sevenDaysAgo = Calendar.current.date(byAdding: .day, value: -7, to: Date())!
let isoStart = ISO8601DateFormatter().string(from: sevenDaysAgo)

let request = Request<[Tick]>(
    baseUrl: URL(string: "https://api-pro.coinpaprika.com/v1/")!,
    method: .get,
    path: "tickers/btc-bitcoin/historical",
    params: ["start": isoStart, "limit": 100, "quote": "usd"],
    userAgent: "my-app/1.0",
    authorisation: .bearer(token: key)
)

request.perform { result in
    switch result {
    case .success(let ticks):
        ticks.forEach { print("[\($0.timestamp)] $\($0.price)") }
    case .failure(let error):
        print("Error fetching historical ticks: \(error)")
    }
}
```

### Search

```swift theme={"dark"}
import Coinpaprika

Coinpaprika.API.search(
    query: "proof-of-work",
    categories: [.tags]
).perform { response in
    switch response {
    case .success(let searchResults):
        print("Found \(searchResults.tags.count) tags for 'proof-of-work'")
        searchResults.tags.forEach { tag in
            print("- \(tag.name) (Coin count: \(tag.coinCounter))")
        }
    case .failure(let error):
        print("Error: \(error)")
    }
}
```

## Error Handling

The `Result` object in the completion handler provides a detailed `RequestError` case for failures.

```swift theme={"dark"}
import Coinpaprika

Coinpaprika.API.coin(id: "invalid-coin-id").perform { response in
    if case .failure(let error) = response {
        switch error {
        case .networkError(let underlyingError):
            print("Network error: \(underlyingError.localizedDescription)")
        case .decodingError(let underlyingError):
            print("Decoding error: \(underlyingError)")
        case .httpError(let statusCode, let data):
            let errorBody = String(data: data, encoding: .utf8) ?? "No response body"
            print("HTTP error \(statusCode): \(errorBody)")
        case .unknown:
            print("An unknown error occurred.")
        }
    }
}
```

## Async/Await Support (iOS 13+ / macOS 10.15+)

The SDK supports modern concurrency with `async/await`.

```swift theme={"dark"}
import Coinpaprika

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
func getMarketData() async {
    do {
        let globalStats = try await Coinpaprika.API.global().async()
        print("Market Cap: $\(globalStats.marketCapUsd)")
        
        let tickers = try await Coinpaprika.API.tickers(quotes: [.usd]).async()
        print("Retrieved \(tickers.count) tickers")
    } catch {
        print("An error occurred: \(error)")
    }
}
```

## Available Methods

### Global Data

* [`global()`](/api-reference/global/get-market-overview-data) - Get global market overview.

### Coins

* [`coins(additionalFields:)`](/api-reference/coins/list-coins) - List all coins.
* [`coin(id:)`](/api-reference/coins/get-coin-by-id) - Get coin by ID.
* [`coinTwitter(id:)`](/api-reference/coins/get-twitter-timeline-tweets-for-a-coin) - Get a coin's Twitter timeline.
* [`coinEvents(id:)`](/api-reference/coins/get-coin-events-by-coin-id) - Get coin events.
* [`coinExchanges(id:)`](/api-reference/coins/get-exchanges-by-coin-id) - Get exchanges for a coin.
* [`coinMarkets(id:quotes:)`](/api-reference/coins/get-markets-by-coin-id) - Get markets for a coin.

### Tickers

* [`tickers(quotes:page)`](/api-reference/tickers/get-tickers-for-all-active-coins) - Get all tickers, with optional pagination.
* [`ticker(id:quotes:)`](/api-reference/tickers/get-ticker-for-a-specific-coin) - Get a specific ticker.
* [`historicalTicks(...)`](/api-reference/tickers/get-historical-ticks-for-a-specific-coin) - Get historical tickers.

### Exchanges

* [`exchanges(quotes:)`](/api-reference/exchanges/list-exchanges) - List all exchanges.
* [`exchange(id:quotes:)`](/api-reference/exchanges/get-exchange-by-id) - Get an exchange by ID.
* [`exchangeMarkets(id:quotes:)`](/api-reference/exchanges/list-an-exchange-markets) - Get markets for an exchange.

### People & Tags

* [`person(id:)`](/api-reference/people/get-person-by-id) - Get a person by ID.
* [`tags(additionalFields:)`](/api-reference/tags/list-tags) - List all tags.
* [`tag(id:additionalFields:)`](/api-reference/tags/get-tag-by-id) - Get a tag by ID.

### Search & Tools

* [`search(...)`](/api-reference/tools/search) - Search across categories.
* [`priceConverter(...)`](/api-reference/tools/price-converter) - Convert between currencies.

### FAQs

<AccordionGroup>
  <Accordion title="How do I use the Pro API in Swift?">
    The high-level <code>Coinpaprika.API</code> static methods don't currently accept a key. Use <code>CoinpaprikaNetworking</code>'s <code>Request\<Model></code> constructor with <code>.bearer(token:)</code> and the <code>[https://api-pro.coinpaprika.com/v1/](https://api-pro.coinpaprika.com/v1/)</code> base URL. See the "Authenticating with a paid plan" section above.
  </Accordion>

  <Accordion title="Where can I find coin IDs for methods like ticker(id:)?">
    Use the [Coverage Checker](/tools/coverage) to obtain canonical IDs (e.g., <code>btc-bitcoin</code>).
  </Accordion>

  <Accordion title="How do I fetch historical ticks/ohlcv?">
    Historical endpoints require a paid plan. Build a <code>Request\<Model></code> against the Pro base URL with <code>.bearer(token:)</code> auth (see the "Authenticating with a paid plan" section), pointing at <code>tickers/{coinId}/historical</code> or <code>coins/{coinId}/ohlcv/historical</code> with <code>start</code>/<code>end</code>/<code>quote</code> parameters.
  </Accordion>

  <Accordion title="What is the recommended error handling?">
    Inspect the failure case of <code>Result</code> and map to app errors; for 429 responses, back off and retry.
  </Accordion>
</AccordionGroup>

## Requirements

* iOS 10.0+ / macOS 10.12+ / watchOS 3.0+ / tvOS 10.0+
* Swift 4.2+

## License

This library is available under the MIT license. See the [LICENSE file](https://github.com/coinpaprika/coinpaprika-api-swift-client/blob/master/LICENSE) for more info.
