# AppleDeveloper
Elixir client for the [App Store Connect API](https://developer.apple.com/documentation/appstoreconnectapi).
It covers the provisioning and App Store Connect surfaces that are most useful in automation scripts and internal tools:
- certificates
- devices
- provisioning profiles
- bundle IDs
- apps
## Installation
Add to your `mix.exs`:
```elixir
defp deps do
[
{:apple_developer, "~> 0.1.0"}
]
end
```
## Configuration
```elixir
config :apple_developer,
issuer_id: System.get_env("APPLE_DEVELOPER_ISSUER_ID"),
key_id: System.get_env("APPLE_DEVELOPER_KEY_ID"),
private_key_path: System.get_env("APPLE_DEVELOPER_PRIVATE_KEY_PATH")
```
Supported options:
- `issuer_id` - App Store Connect issuer ID
- `key_id` - App Store Connect API key ID
- `private_key` - inline `.p8` contents
- `private_key_path` - path to the `.p8` file
- `base_url` - defaults to `https://api.appstoreconnect.apple.com`
- `token_ttl_seconds` - defaults to `1200`
- `req_options` - forwarded to `Req`
Every public function accepts per-call overrides.
## Quick Start
```elixir
# Access token
{:ok, token} = AppleDeveloper.token()
# Apps
{:ok, apps} = AppleDeveloper.list_apps(limit: 5)
# Certificates
{:ok, certs} = AppleDeveloper.list_certificates(filter_status: "ACTIVE")
# Devices
{:ok, devices} = AppleDeveloper.list_devices(filter_platform: "IOS")
# Profiles
{:ok, profiles} = AppleDeveloper.list_profiles(filter_profile_state: "ACTIVE")
```
## Common Operations
```elixir
# Register a device
AppleDeveloper.register_device(
"QA iPhone",
"00008110-001234567890ABCDE",
"IOS"
)
# Create a development certificate
AppleDeveloper.create_certificate(:ios_development, csr_pem)
# Create a provisioning profile
AppleDeveloper.create_profile(
"My Development Profile",
"IOS_APP_DEVELOPMENT",
bundle_id_id,
[certificate_id],
[device_id]
)
```
## Live Testing
A live smoke test is included:
```bash
cd apple_developer
elixir test_live.exs
```
That script verifies token generation and makes a real `list_apps` call.
## Errors
API calls return `{:ok, result}` or `{:error, reason}`.
HTTP failures are wrapped in `AppleDeveloper.Error`.
Typical statuses:
- `401` - invalid key, issuer, or expired token
- `403` - permissions issue
- `404` - resource not found
- `422` - validation failure
- `429` - rate limited
## Notes
- The client uses the JWT directly as the bearer token.
- Tokens are cached in `AppleDeveloper.TokenCache` with a 60-second refresh buffer.
- The package is suitable for CI tooling and one-off release automation scripts.
## License
MIT