# Sybilion R SDK

Official R client for the [Sybilion API](https://sybilion.dev/docs/).

## Install

From a local checkout:

```r
install.packages(c("jsonlite", "httr2", "R6", "base64enc", "stringr"))
install.packages("path/to/developers-portal-api-sdk-r", repos = NULL, type = "source")
```

## Configuration

- Credential: pass `token` to `sybilion_client()` or `Client$new()` (alias: `api_key`).
- Base URL: `base_url` / `api_url`, else `SYBILION_API_BASE_URL`, else `DEFAULT_PUBLIC_API_BASE_URL` (`https://api.sybilion.dev`).

## Quick use (me)

```r
library(sybilion)

cl <- sybilion_client(
  token = Sys.getenv("SYBILION_API_TOKEN"),
  base_url = "https://api.sybilion.dev"
)
me <- cl$raw$ApiV1MeGet()
```

Use `Client`/`sybilion_client()` for Bearer setup; `iter_usage_pages` and `iter_jobs_pages` mirror Go/Python pagination helpers; `wait_forecast` polls until settled.

## Forecasting (end-to-end)

```r
library(jsonlite)
library(sybilion)

cl <- sybilion_client(token = Sys.getenv("SYBILION_API_TOKEN"))
cl$raw$ApiV1MeGet()

payload <- jsonlite::fromJSON("forecast_post_example.json")

req <- ForecastRequestV1$new(
  frequency = payload$frequency,
  pipeline_version = payload$pipeline_version,
  recency_factor = payload$recency_factor,
  timeseries = payload$timeseries,
  timeseries_metadata = TimeseriesMetadata$new(
    title = payload$timeseries_metadata$title,
    description = payload$timeseries_metadata$description,
    keywords = payload$timeseries_metadata$keywords
  ),
  backtest = payload$backtest,
  hard_horizon = payload$hard_horizon,
  soft_horizon = payload$soft_horizon,
  strictly_positive = payload$strictly_positive
)

if (!is.null(payload$filters)) {
  req$filters <- Filters$new(
    categories = payload$filters$categories,
    regions = payload$filters$regions,
    limit = payload$filters$limit
  )
}

started <- cl$raw$ApiV1ForecastsPost(req)
job <- cl$wait_forecast(started$job_id, poll_s = 2, timeout_s = 1800)
```

To bring your own forecast drivers, set `ForecastRequestV1$aux_timeseries` to a list of 1–10 series, each a named numeric list keyed on the same dates as `timeseries`:

```r
ForecastRequestV1$new(
  pipeline_version = "v1", frequency = "monthly", recency_factor = 0.5,
  soft_horizon = 12, timeseries_metadata = meta, timeseries = ts,
  aux_timeseries = list(
    list(`2015-01-01` = 1.2, `2015-02-01` = 1.4),
    list(`2015-01-01` = 9.0, `2015-02-01` = 8.7)
  )
)
```

## Discover categories and regions

```r
library(sybilion)

cl <- sybilion_client(token = Sys.getenv("SYBILION_API_TOKEN"))

cats <- cl$raw$ApiV1CategoriesGet()
# cats$content is a CategoryListResponse; each item has $id and $name
for (cat in cats$content$items) {
  cat(sprintf("category id=%d  name=%s\n", cat$id, cat$name))
}

regions <- cl$raw$ApiV1RegionsGet()
# regions$content is a RegionListResponse; each item has $id, $name, $latitude, $longitude
for (r in regions$content$items) {
  cat(sprintf("region id=%d  name=%s  lat=%.2f  lon=%.2f\n",
              r$id, r$name, r$latitude, r$longitude))
}
```

## Download an artifact

```r
a <- job$artifacts[[1]]
cl$raw$ApiV1ForecastsIdArtifactsNameGet(job$job_id, a$name, data_file = file.path("out", a$name))
```

## Maintainer commands

```bash
bash scripts/sync-from-api-repo.sh   # copy openapi.public.yaml → openapi/openapi.yaml
bash scripts/sdk-generate-r.sh       # regenerate R + docs (Docker); preserves R/client.R, R/env.R, R/defaults.R
bash scripts/sdk-verify-r.sh
make verify
```

## Documentation

Full guides, feature walkthroughs, API reference, and SDK patterns: **<https://sybilion.dev/docs/>**.

## Support

- Email — [support@sybilion.com](mailto:support@sybilion.com)
- Slack — [Sybilion Community](https://join.slack.com/t/sybilioncommunity/shared_invite/zt-3y6vx56nk-WJu35eLxkyFQr~Yfko6RjQ)
- Discord — [Sybilion Developers Community]( https://discord.com/invite/KMDyXBdQ8c)

