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

# Installation

> Install the SDK from your own site, then point it at the site.

**1. Install the SDK from your site**

Your own site serves the SDK, and any API key from it lets you in. In a terminal, in your Laravel
app's folder, run:

```bash Terminal theme={"dark"}
composer config repositories.fetchski composer https://acme.example/api/v1/sdk/composer
composer config bearer.acme.example fsk_acme_…
composer require fetchski/attract-cms-laravel
```

The first line tells Composer the SDK comes from your site (it's saved in `composer.json`). The second
saves your key in the app's `auth.json`. The third installs the SDK, and the API client it uses, from
your site. Put your site's address in the first two lines (set your site in the bar under this page's
title and the example shows it), and paste your whole key in place of `fsk_acme_…`.

> [!NOTE]
>
> **Any API key from your site works**, the same one your app uses included: its scopes and signing
> mode don't matter for installing, only that it's switched on and not past its expiry date. No key
> yet? Make one in the CMS under **API Keys** ([Authentication](https://docs.fetchski-attract.com/authentication.md)).

> [!WARNING]
>
> **`auth.json` holds a key to your site: never commit it.** A Laravel app's `.gitignore` already
> lists `/auth.json`; keep that line there (add it if yours doesn't have it). In CI, write the same
> `auth.json` from a secret before installing.

> [!TIP]
>
> **`401 Unauthorized`?** Your site refused the key in `auth.json`: it's mistyped or cut short,
> switched off, or past its expiry date. Run the second line again with the right key.

The service provider registers itself.

**2. Install it into the app**

```bash theme={"dark"}
php artisan attract:install
```

It publishes `config/fetchski-attract.php`, asks for the site's slug, URL and API key, then the
key's signing secret (leave it empty for a token-only key), and writes them to `.env` (and empty
ones to `.env.example`, when the app has one). Then it calls the site to check it's reachable, the
key is accepted and the clocks agree. With no secret, a `FETCHSKI_ATTRACT_SIGNING_SECRET` left in
`.env` by an earlier key is removed.

> [!TIP]
>
> In CI or a script, give every value as an option and nothing is asked (leave `--secret` out for a
> token-only key, and add `--no-check` to skip the check):
>
> ```bash Terminal theme={"dark"}
> php artisan attract:install \
>   --site=acme \
>   --url=https://acme.example \
>   --key=fsk_acme_… \
>   --secret=fss_…
> ```

Rather keep the key out of `.env`? Store it encrypted in a table the package ships instead (see
[Key in the database](https://docs.fetchski-attract.com/laravel/key-in-database.md)):

```bash Terminal theme={"dark"}
php artisan attract:install --database
```

**3. Give your coding agent the skill**

```bash theme={"dark"}
DISABLE_TELEMETRY=1 npx skills add ./vendor/fetchski/attract-cms-laravel/skills
```

The package's [Agent Skill](https://docs.fetchski-attract.com/agent-skills.md), installed for the agents you pick, so they call
the SDK the way these guides do.

## Requirements

> [card] Laravel 12 or 13
>
> The service provider, the facade and the Artisan commands.

> [card] PHP 8.5.12+
>
> Earlier releases carry severe security vulnerabilities.

> [card] Guzzle 7.10+ or 8.3+
>
> Whichever your app's other packages need: a new Laravel 13 app ships Guzzle 8.

> [card] [Next: configuration](https://docs.fetchski-attract.com/laravel/configuration.md)
>
> One site from `.env`, more by hand, or a table.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.