## 1. Project Overview & Quickstart (apollographql/apollo-kotlin)

## File: README.md

<header>
  
    
  <h1 align="center">Apollo Kotlin</h1>
 
**The industry-leading GraphQL client for Kotlin**. Run on Android and all the Kotlin multiplatform targets. Apollo Kotlin delivers powerful caching, code generation, intuitive APIs, and comprehensive developer tools to accelerate your app development.
</header>


## ❓ Why Choose Apollo Kotlin?

 ✅ 100% type safety, from your server to your app, using code generation
 ✅ Intuitive, powerful caching - intelligent in-memory or SQLite caching out of the box
 ✅ Excellent support for modern Android and Kotlin Multiplatform apps
 ✅ Always up-to-date - we prioritize support for the latest versions of GraphQL, Kotlin, Gradle, and more
 ✅ GraphOS ready - turnkey support for Persisted Queries, and `@defer`
 ✅ Production-tested - Powers countless apps worldwide that serve millions of end users

 ## 🚀 Quick Start
 
If you are new to GraphQL, check out [the tutorial](https://www.apollographql.com/tutorials/apollo-kotlin-android-part1) that will guide you through building an Android app using Apollo.

For more in-depth documentation, head to the [official documentation site](https://www.apollographql.com/docs/kotlin?utm_source=github&utm_medium=apollographql_apollo-kotlin&utm_campaign=readme).

For a detailed "Get Started" guide, check out our [docs](https://www.apollographql.com/docs/kotlin?utm_source=github&utm_medium=apollographql_apollo-kotlin&utm_campaign=readme).

## 💡 Resources

| Resource | Description | Link |
| ----- | ----- | ----- |
| **Full Documentation** | Comprehensive guides and examples | [Read Docs →](https://www.apollographql.com/docs/kotlin?utm_source=github&utm_medium=apollographql_apollo-kotlin&utm_campaign=readme) |
| **API Reference** | Complete API documentation | [Browse Kdoc →](https://apollographql.github.io/apollo-kotlin/kdoc/older/4.2.0/index.html?utm_source=github&utm_medium=apollographql_apollo-kotlin&utm_campaign=readme) |
| **IntelliJ Plugin** | Enhanced development experience | [Install Plugin →](https://plugins.jetbrains.com/plugin/20645-apollo-graphql) |
| **Free Course** | Learn GraphQL and Apollo Client | [Take Course →](https://www.apollographql.com/tutorials/apollo-kotlin-android-part1?utm_source=github&utm_medium=apollographql_apollo-kotlin&utm_campaign=readme) |

## 🧑‍🚀 About Apollo 

Deliver tomorrow's roadmap today with our comprehensive suite of API orchestration tools:

* [**Apollo Client**](https://www.apollographql.com/docs/react?utm_source=github&utm_medium=apollographql_apollo-kotlin&utm_campaign=readme) \- Type-safe apps with GraphQL-powered on-device caching ([React](https://www.apollographql.com/docs/react?utm_medium=github&utm_source=apollographql_apollo-kotlin&utm_campaign=readme), [iOS](https://www.apollographql.com/docs/ios?utm_medium=github&utm_source=apollographql_apollo-kotlin&utm_campaign=readme), [Kotlin](https://www.apollographql.com/docs/kotlin?utm_medium=github&utm_source=apollographql_apollo-kotlin&utm_campaign=readme))  
* [**Apollo Connectors**](https://www.apollographql.com/graphos/apollo-connectors?utm_source=github&utm_medium=apollographql_apollo-kotlin&utm_campaign=readme) \- Compose all your GraphQL and REST APIs into one GraphQL endpoint  
* [**Apollo MCP Server**](https://www.apollographql.com/apollo-mcp-server?utm_source=github&utm_medium=apollographql_apollo-kotlin&utm_campaign=readme) \- AI needs APIs. The fastest way to ship reliable AI experiences  
* [**Apollo Router**](https://www.apollographql.com/docs/router?utm_source=github&utm_medium=apollographql_apollo-kotlin&utm_campaign=readme) \- Scale your APIs seamlessly with GraphQL Federation, Security, Auth, and more  
* [**GraphOS**](https://www.apollographql.com/graphos?utm_source=github&utm_medium=apollographql_apollo-kotlin&utm_campaign=readme) \- Deploy, manage, govern, and explore your APIs ([start for free, no credit card needed](https://www.apollographql.com/pricing?utm_medium=github&utm_source=apollographql_apollo-kotlin&utm_campaign=readme))

[**Explore the Complete Apollo Platform →**](https://www.apollographql.com/?utm_source=github&utm_medium=apollographql-_apollo-kotlin&utm_campaign=readme)

## 🛠️ Maintained by

|Name|Username|
|---|---|
|Benoit Lubek|[@bod](https://github.com/bod)|
|Jeff Auriemma|[@bignimbus](https://github.com/bignimbus)|
|Martin Bonnin|[@martinbonnin](https://github.com/martinbonnin)|

## 🗺️ Roadmap

We regularly update our [public roadmap](https://github.com/apollographql/apollo-kotlin/blob/main/ROADMAP.md) with the status of our work-in-progress and upcoming features.

## 📣 Tell us what you think

| ☑️  Apollo Kotlin User Survey |
| :----- |
| What do you like best about Apollo Kotlin? What needs to be improved? Please tell us by taking a [one-minute survey](https://docs.google.com/forms/d/e/1FAIpQLSczNDXfJne3ZUOXjk9Ursm9JYvhTh1_nFTDfdq3XBAFWCzplQ/viewform?usp=pp_url&entry.1170701325=Apollo+Kotlin&entry.204965213=Readme). Your responses will help us understand Apollo Kotlin usage and allow us to serve you better. |

## 🗓️ Events

Join these live events to meet other GraphQL users and learn more: 

🎪 [**Apollo Summit 2026**](https://apollosummit.dev/)
 Oct 6-8, 2026 • San Francisco  
 *1000+ engineers, talks, workshops, and office hours*

[**View All Events →**](https://www.apollographql.com/events?utm_source=github&utm_medium=apollographql_apollo-kotlin&utm_campaign=readme)

## 🏆 Contributing

Thank you for your interest in submitting a Pull Request to Apollo Kotlin!  Read our [guidelines](https://github.com/apollographql/apollo-kotlin/blob/main/CONTRIBUTING.md) first, and don't hesitate to get in touch.

**New to open source?** Check out our [**Good First Issues**](https://github.com/apollographql/apollo-kotlin/issues?q=is%3Aopen%20label%3A%22%3Abooks%3A%20good-first-issue%22) to get started.

## 🤝 Code of Conduct

Please read our [Code of Conduct](https://community.apollographql.com/faq). This applies to any space run by Apollo, including our GitHub repositories, the Apollo GraphOS Discord, the Apollo GraphQL Forum. The Code of Conduct reflects our commitment to making the Apollo Community a welcoming and safe space in which individuals can interact.

## 🪪 License

Source code in this repository is available under the terms of the MIT License.  Read the full text [here](https://github.com/apollographql/apollo-kotlin/blob/main/LICENSE).

---

## File: benchmark/app/README.md

A small app to monitor start performance and also to pass as an (unused) app apk to Firebase test labs for microbenchmarks.

---

## File: benchmark/README.md

# Benchmark

This is a standalone Android Studio project to benchmark performance. 

## Running the tests

You can run the tests from Android Studio by clicking the "run" icon in the gutter. This will
print the results in the `Run` window of Android Studio.

For the command line, use:

```
# macrobenchmarks
./gradlew -p benchmark :macrobenchmark:connectedBenchmarkAndroidTest 

# microbenchmarks
./gradlew -p benchmark :microbenchmark:benchmarkReport
```

## Inspiration

The `largesample` Json parsing data is taken from https://zacsweers.github.io/json-serialization-benchmarking/.
The `calendar_response` data was provided by @sebj and is a real-life use case.
The `tracks` data is inspired by the Deezer API.

## Current results:

You can get the current results at https://github.com/apollographql/apollo-kotlin/issues/4231

---

## File: build-logic/README.md

# build-logic

A simple JVM project that contains the shared build logic.

It also contains all the buildscript dependencies so that we don't have to specify versions in each module `plugins {}` block.

---

## File: design-docs/Readme.md

## Design docs

This is Apollo Kotlin documentation for how things work under the hood. The user-facing documentation about how to use Apollo Kotlin is available at https://www.apollographql.com/docs/android/.

This internal documentation is work in progress. It is used for brainstorming/communication but might be lagging sometimes, feel free to send PRs!

---

## File: docs/source/advanced/apollo-ast.mdx

---
title: Apollo AST
---

To generate client code, Apollo Kotlin parses both your GraphQL schema _and_ each operation you write against it into an **Abstract Syntax Tree** ([AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree)). An AST represents a GraphQL document in a type-safe, machine-readable format.

The Apollo Kotlin parser has its own artifact (`apollo-ast`), which you can use independently of `apollo-runtime` or `apollo-api`.

Features of `apollo-ast` include:

- [Parsing schema and operation documents](#parsing-a-document) into abstract syntax trees (ASTs)
- Providing [input validation](#validating-input) to raise warnings and errors (See the [GraphQL spec](https://spec.graphql.org/draft/#sec-Validation))
- Support for [outputting ASTs](#outputting-sdl) as valid, indented GraphQL documents
- Support for manipulation of ASTs via the [`transform` API](#transforming-an-ast)

## Installation

Add the `apollo-ast` dependency to your project:

```kotlin title="build.gradle[.kts]"
dependencies {
  // ...

  implementation("com.apollographql.apollo:apollo-ast:5.1.0")
}
```

## Parsing a document

Use the `parseAsGQLDocument` method to parse a document from a `File`, a `String`, or an Okio [`BufferedSource`](https://square.github.io/okio/3.x/okio/okio/okio/-buffered-source/index.html).

```kotlin {13}
val graphQLText = """
    query HeroForEpisode(${"$"}ep: Episode) {
      hero(episode: ${"$"}ep) {
        name
        friends {
          height
        }
        foobar
      }
    }
""".trimIndent()

val parseResult = graphQLText.parseAsGQLDocument()
```

This method returns a `GQLResult<GQLDocument>`, which contains the document and/or parsing issues, each of which can have a severity of either `WARNING` or `ERROR`. Because there can be warnings, it is possible to have both a valid document and issues at the same time.

To get the document and throw on errors, use `getOrThrow()`:

```kotlin
val queryGqlDocument = parseResult.getOrThrow()
```

`GQLDocument` is the root of the AST. It contains a list of `GQLDefinition`s that together represent the GraphQL document.

All nodes in an AST are subclasses of `GQLNode` (all named with the `GQL` prefix). Each subclass exposes specific properties and methods relevant to the corresponding node type.

### Example AST structure

In the `HeroForEpisode` example [above](#parsing-a-document), here's the structure of the AST returned by the parser:

```
GQLDocument
    └─GQLOperationDefinition query "HeroForEpisode"
        ├─GQLVariableDefinition "ep": "Episode"
        └─GQLSelectionSet
            └─GQLField "hero"
                ├─GQLSelectionSet
                │   ├─GQLField "name"
                │   ├─GQLField "friends"
                │   │   └─GQLSelectionSet
                │   │       └─GQLField "height"
                │   └─GQLField "foobar"
                └─GQLArguments
                    └─GQLArgument "episode"
                        └─GQLVariableValue "ep"
```

Note that this structure and its node names closely follow the [GraphQL specification](https://spec.graphql.org/June2018/#sec-Appendix-Grammar-Summary.Document).

## Validating input

In addition to parsing, the `apollo-ast` library provides methods to perform higher-level validation of GraphQL documents.

To validate a parsed `GQLDocument`:

* **If the document represents a schema,** call the `validateAsSchema` method.
* **If the document represents one or more operations,** call the `validateAsExecutable` method.

### `validateAsSchema`

`validateAsSchema` returns a `GQLResult<Schema>`. The following snippet parses and validates a short invalid schema that uses an undefined directive (`@private`):

```kotlin {11,19}
val schemaText = """
    type Query {
      hero(episode: Episode): Character
    }

    enum Episode {
      NEWHOPE
      EMPIRE
    }

    type Character @private {
      name: String
      height: Int @deprecated
      friends: [Character]
    }
""".trimIndent()

val schemaGQLDocument = schemaText.parseAsGQLDocument().getOrThrow()
val schemaResult = schemaGQLDocument.validateAsSchema()
println(schemaResult.issues.map { it.severity.name + ": " + it.message })
```

When executed, this snippet prints `[WARNING: Unknown directive 'private']`.

Because this is a warning and not an error, you can still use the returned `schemaResult.getOrThrow()`

### `validateAsExecutable`

The `validateAsExecutable` method checks whether a document's defined operations are valid against a particular provided `Schema`. You can obtain this `Schema` parameter by calling the [above](#validateAsSchema) `validateAsSchema` on the `GQLDocument` that represents the schema:

```kotlin
val schema = schemaGQLDocument.validateAsSchema().getOrThrow()
val executableIssues = queryGqlDocument.validateAsExecutable(schema)
println(executableIssues.map { it.severity.name + ": " + it.message })
```

If the `queryGqlDocument` queries a deprecated field and misspells another, this snippet might print the following:

```
[WARNING: Use of deprecated field 'height', ERROR: Can't query 'frends' on type 'Character']
```

## Outputting SDL

You can output a `GQLDocument` to standard GraphQL syntax with the `toUtf8` extensions:

```kotlin
// Returns a string
println(queryGqlDocument.toUtf8())

// Output to a File
queryGqlDocument.toUtf8(file)
```

## Transforming an AST

You can use the `transform` method of `GQLDocument` to modify an existing AST.

You pass `transform` a lambda that accepts a `GQLNode` and also returns instructions to manipulate the AST:

- `Continue`: keep the node as-is and continue visiting the children
- `Delete`: delete the node
- `Replace(GQLNode)`: replace the node with the given one

The `transform` method traverses the AST and executes the lambda for each node, then acts on the AST according to the lambda's return value.

Note that with `Delete` and `Replace`, the node's children are not visited automatically, so you should call `transform`
recursively if that is needed.

For example, this snippet removes all fields named `restrictedField` from operations defined in `queryGqlDocument` and prints the result:

```kotlin
val transformedQuery = queryGqlDocument.transform{ node ->
  if (node is GQLField && node.name == "restrictedField") {
    TransformResult.Delete
  } else {
    TransformResult.Continue
  }
}
println(transformedQuery!!.toUtf8())
```

---

## File: docs/source/advanced/authentication.mdx

---
title: Authenticate your operations
---

> Authentication is not included in the GraphQL specification. This page aims at giving some guidance for the most common scenarios but doesn't intend to be exhaustive.

## Authenticating your HTTP requests with OkHttp

[OkHttp Interceptors](https://square.github.io/okhttp/features/interceptors/) are an easy way to add an `"Authorization"` header to your HTTP requests.

OkHttp Interceptors have been around for a long time and work well but can only be used with Apollo Kotlin on Android and the JVM.

## Authenticating your HTTP requests with Apollo HttpInterceptor

To authenticate your HTTP requests in a multi-platform way, you can use an Apollo [HttpInterceptor](./interceptors-http).

HttpInterceptor is multiplatform and uses an API very similar to OkHttp's:

```kotlin
class AuthorizationInterceptor() : HttpInterceptor {
  private val mutex = Mutex()

  override suspend fun intercept(request: HttpRequest, chain: HttpInterceptorChain): HttpResponse {
    var token = mutex.withLock {
      // get current token
    }

    val response = chain.proceed(request.newBuilder().addHeader("Authorization", "Bearer $token").build())

    return if (response.statusCode == 401) {
      token = mutex.withLock {
        // get new token
      }
      chain.proceed(request.newBuilder().addHeader("Authorization", "Bearer $token").build())
    } else {
      response
    }
  }
}
```

For a more advanced example, you can take a look at the [AuthorizationInterceptor integration tests](https://github.com/apollographql/apollo-kotlin/blob/6f0b798198c215013f12e7da509624a1befc1b73/apollo-runtime/src/commonTest/kotlin/com/apollographql/apollo3/network/AuthorizationInterceptor.kt#L30)

## Authenticate your subscriptions with an HTTP header or query parameter

`ApolloClient` creates different WebSockets for different header values. Use an interceptor to change the header value on error:

```kotlin
private class UpdateAuthorizationHeaderInterceptor : ApolloInterceptor {
  @OptIn(ExperimentalCoroutinesApi::class)
  override fun <D : Operation.Data> intercept(request: ApolloRequest<D>, chain: ApolloInterceptorChain): Flow<ApolloResponse<D>> {
    return flow {
      // Retrieve a new access token every time
      val request = if (request.operation is Subscription<*>) {
        request.newBuilder()
            // Update the HTTP header
            .addHttpHeader("Authorization", "Bearer ${accessToken()}")
            // Or change the url
            .url("https://example.com/subscription?token=${accessToken()}")
            .build()
      } else {
        request
      }

      emitAll(chain.proceed(request))
    }
  }
}
```

Note: The client shares WebSockets in a pool. If your access token changes frequently, the client might open multiple WebSockets concurrently.

## Authenticate your subscriptions with a connection payload

The connection payload is specific to the `WsProtocol`. Pass a lambda to the `WsProtocol` constructor that the client evaluates whenever it creates a WebSocket.

```kotlin
ApolloClient.Builder()
  .httpServerUrl(mockServer.url())
  .subscriptionNetworkTransport(
      WebSocketNetworkTransport.Builder()
          .serverUrl(mockServer.url())
          .wsProtocol(GraphQLWsProtocol(
              connectionPayload = {
                getFreshConnectionPayload()
              }
          ))
          .build()
  )
  .build()
```

## Retry your subscriptions automatically

The preceding approaches require your backend to indicate when a token expires. Unlike HTTP 401 errors, WebSockets lack a widespread standard for expiration signaling.

If your backend closes the WebSocket, retry subscriptions automatically using `retryOnError { it.operation is Subscription }`:

```kotlin
ApolloClient.Builder()
  .serverUrl(mockServer.url())
  .retryOnError { it.operation is Subscription }
```

For other cases, customize your `RetryStrategy`. For details, see [Network errors](network-errors).

---

## File: docs/source/advanced/client-awareness.mdx

---
title: Client Awareness
---

GraphOS Studio users can opt in [Client Awareness](https://www.apollographql.com/docs/graphos/metrics/client-awareness/). Client Awareness allows you to view operation metrics split per client, helping you understand how each one interacts with your graph.

Client Awareness uses `apollographql-client-name` and `apollographql-client-version` custom HTTP headers to report client usage.

Enable it by adding an `ApolloClientAwarenessInterceptor` to your `ApolloClient`:

```kotlin
val apolloClient = ApolloClient.Builder()
    .serverUrl("https://example.com/graphql")
    .addHttpInterceptor(ApolloClientAwarenessInterceptor(BuildConfig.APPLICATION_ID, BuildConfig.VERSION_NAME))
    .build()
```

<Note>

This example uses `BuildConfig` to set the app's `applicationId` as the client name and its `versionName` as the client version, but you can override this. Especially, if your iOS and Android apps use the same package name, it's useful to customize it to be able to differentiate the clients.

</Note>

---

## File: docs/source/advanced/compiler-plugins.mdx

---
title: Apollo compiler plugins
---

<ExperimentalFeature>

**Compiler plugins are currently [experimental](https://www.apollographql.com/docs/resources/product-launch-stages/#experimental-features) in Apollo Kotlin.** If you have feedback on them, please let us know via [GitHub issues](https://github.com/apollographql/apollo-kotlin/issues/new?assignees=&labels=Type%3A+Bug&template=bug_report.md) or in the [Kotlin Slack community](https://slack.kotl.in/).

</ExperimentalFeature>

The Apollo compiler supports [a wide range of options](../advanced/plugin-configuration). For the cases where these options are not enough, you can use Apollo compiler plugins to modify the behaviour of the compiler. 

Apollo compiler plugins allow to:

* Change the layout of the generated sources (name of the classes, package names, capitalization rules).
* Change the ids of operation for persisted queries.
* Transform the JavaPoet/KotlinPoet models.
* Transform the Apollo IR.

## Implementing a compiler plugin

In this example we will implement a plugin that uses custom [persisted queries](../advanced/persisted-queries) ids registered on your backend. 

The Apollo compiler use the [ServiceLoader API](https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html) to load plugins at runtime. Plugins need to be implemented in a separate module that is added to the classpath.

To start, create a new Gradle module and add `apollo-compiler` as a dependency to the module `build.gradle[.kts]` file. In this example, we'll use `apollo-compiler-plugin` as module name:

```kotlin
// apollo-compiler-plugin/build.gradle.kts
plugins {
  id("org.jetbrains.kotlin.jvm")
}

dependencies {
  // Add apollo-compiler as a compileOnly dependency
  compileOnly("com.apollographql.apollo:apollo-compiler:5.1.0")  
}
```

Next create your plugin in a `src/main/kotlin/mypackage/MyPlugin` file:

```kotlin
class MyPlugin: ApolloCompilerPlugin {
  override fun beforeCompilationStep(
      environment: ApolloCompilerPluginEnvironment,
      registry: ApolloCompilerRegistry,
  ) {
    // add your custom code here
  }
}
```


Make your plugin discoverable by [ServiceLoader](https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html) by adding a resource in `src/main/resources/META-INF/services/com.apollographql.apollo.compiler.ApolloCompilerPlugin`. This file contains the fully qualified name of your plugin: 

```
mypackage.MyPlugin
```

<Note>

The name of the resource file is important. It must be `com.apollographql.apollo.compiler.ApolloCompilerPlugin` and be in the `META-INF/services` folder. This is how `ServiceLoader` looks up plugins at runtime.
</Note>


## Adding a plugin to the Apollo compiler classpath

Use the `Service.plugin()` Gradle method to add the plugin to the Apollo compiler classpath:

```kotlin
// app/build.gradle.kts
plugins {
  id("org.jetbrains.kotlin.jvm")
  id("com.apollographql.apollo")
}

apollo {
  service("service") {
    packageName.set("com.example")
    
    // Add your plugin to the Apollo compiler classpath
    plugin(project(":apollo-compiler-plugin")) // highlight-line
  }
}
```

The plugin code will now be invoked the next time the compiler is invoked.

## Passing arguments to your Apollo compiler plugin

Because the compiler plugin runs in an isolated classpath, you can't use classes or data from your main build logic classpath. 

In order to pass build-time arguments to your Apollo compiler plugin, use `pluginArgument()`:

```kotlin
apollo {
  service("service") {
    packageName.set("com.example")
    
    // Add your plugin to the Apollo compiler classpath
    plugin(project(":apollo-compiler-plugin"))
    // Add argument
    pluginArgument("com.example.token", token) // highlight-line
  }
}
```

Note that arguments are shared between all compiler plugins and using a prefix such as your plugin package name is recommended to avoid name clashes.

The arguments are available in `ApolloCompilerPluginEnvironment.arguments`:

```kotlin
class MyPlugin: ApolloCompilerPlugin {
  override fun beforeCompilationStep(
      environment: ApolloCompilerPluginEnvironment,
      registry: ApolloCompilerRegistry,
  ) {
    val token = environment.arguments.get("token") as String
    
    // add your custom code here
  }
}
```

Arguments must be serializable and be instances of classes accessible from the bootstrap classloader. In practice, built-in types and collections are supported.

## Other references

For other plugin APIs like layout, IR, JavaPoet and KotlinPoet transforms, check out the [ApolloCompilerPlugin API docs](https://www.apollographql.com/docs/kotlin/kdoc/apollo-compiler/com.apollographql.apollo.compiler/-apollo-compiler-plugin/index.html)

For more examples, check out the [integration-tests](https://github.com/apollographql/apollo-kotlin/tree/main/tests/compiler-plugins).

## 2. Official Technical Reference & Guides (apollographql/docs)

This repository contains an archived version of the documentation platform for the [Apollo Documentation site](https://www.apollographql.com/docs/). It is no longer actively maintained, and the content here may be outdated. The project has undergone significant updates, and the latest documentation platform is now maintained in a private repository.

To update documentation content for Apollo’s open-source and source-available SDKs and libraries, you can submit pull requests to the relevant repository:

- [Apollo Client](https://github.com/apollographql/apollo-client)
- [Apollo Kotlin](https://github.com/apollographql/apollo-kotlin)
- [Apollo iOS](https://github.com/apollographql/apollo-ios)
- [Apollo Server](https://github.com/apollographql/apollo-server)
- [Apollo Router](https://github.com/apollographql/router)
- [Apollo Federation](https://github.com/apollographql/federation)
- [Rover CLI](https://github.com/apollographql/rover)

To submit feedback about the documentation, please use the **Give Feedback** option at the bottom of documentation content pages.