# Laravel Integration (`sovanza.inc/laravel-integration`) Actor

Laravel Integration connects Laravel apps with Apify to run Actors, process trigger datasets, send signed webhook callbacks, forward dataset IDs, and support scraper orchestration, queue workflows, and Actor chaining.

- **URL**: https://apify.com/sovanza.inc/laravel-integration.md
- **Developed by:** [Sovanza](https://apify.com/sovanza.inc) (community)
- **Categories:** Developer tools, Automation, Integrations
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $8.00 / 1,000 integration runs

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

### Laravel Integration – Apify Automation Bridge for PHP Apps

Integrate the **Laravel** web application framework with the **Apify** platform to simplify building automation and web scraping APIs. This Actor acts as an **integration layer**: your Laravel app passes static configuration (webhook URL, API token, queue name) and dynamic scraper parameters, and this Actor runs other Apify Actors, processes integration trigger payloads, and calls back to Laravel with run status and dataset IDs.

### Overview

This Laravel Integration Actor connects PHP applications to Apify using **static Laravel settings** (webhook URL, secrets, queue, correlation ID) and **dynamic trigger data** (dataset ID, run ID, key-value store ID from integration webhooks). It is built for Laravel developers, backend engineers, and agencies who need a reusable bridge for **scraper orchestration**, **webhook callbacks**, and **Actor chaining** without reimplementing Apify integration logic in every project.

**Integration-ready by design:** dynamic fields are read from the implicit `payload` field attached by Apify integration triggers, so users only configure the static Laravel side in most cases.

### Key benefits

- Start any Apify scraper from **Laravel controllers, jobs, or artisan commands**  
- Receive **progress and completion callbacks** on your own HTTPS endpoints  
- Chain Actors with Apify **Integrations** (when a scraper finishes, process its dataset automatically)  
- Forward **dataset IDs** (not full webhook payloads) and optionally preview rows  
- Use **Apify Proxy** and **retries** for production reliability  
- Export integration results in **JSON, CSV, or Excel** via Apify  

### Core features

- **Run any Actor** (`mode=run_actor`): call `targetActorId` with `targetActorInput` from Laravel  
- **Laravel webhooks**: POST callbacks to `laravelWebhookUrl` with optional HMAC `X-Apify-Signature`  
- **Integration triggers**: reads `payload.resource.defaultDatasetId` from Apify integration webhooks automatically  
- **Process trigger datasets** (`mode=process_trigger`): copy source dataset rows into this run's dataset in batches  
- **Forward to Laravel** (`mode=forward_dataset`): send dataset metadata (and optional preview) to your app  
- **Static vs dynamic input**: Laravel config is static; trigger fields come from `payload` or advanced overrides  
- **Apify Proxy**: optional `proxyConfiguration` merged into child Actor input when `mergeProxyIntoTargetActor` is true  
- **Retries**: configurable retries for `Actor.call()` and Laravel webhook HTTP requests  
- **Health check**: `runHealthCheckOnStart: true` for Apify Console Try actor / CI validation  

### How to Use Laravel Integration on Apify

#### Using the Actor

1. **Open the Actor** on the Apify platform and go to the **Input** tab.  
2. **Configure input** (see below): set `mode`, Laravel webhook settings, and either `targetActorId` + `targetActorInput` or rely on integration trigger `payload`.  
3. **Start** the run. The Actor calls child Actors, processes trigger datasets, or forwards results, and **pushes summary rows** to the default dataset.  
4. **Open the Dataset** tab to browse integration summaries, copied rows, or download JSON/CSV/Excel.  
5. **Schedule or integrate** (optional): connect this Actor on another Actor's **Integrations** tab, use webhooks, or call from Laravel via `apify-client`.  

#### Input Configuration

Full schema: `INPUT_SCHEMA.json`. Example (run Python Scraper from Laravel — no cookies required):

```json
{
  "mode": "run_actor",
  "targetActorId": "sovanza.inc/python-scraper",
  "startUrls": ["https://example.com"],
  "targetActorInput": {
    "startUrls": ["https://example.com"],
    "includeLinks": true,
    "includeHtml": false,
    "exportFormat": "json"
  },
  "laravelWebhookUrl": "https://your-app.test/api/apify/webhook",
  "laravelWebhookSecret": "your-shared-secret",
  "laravelBaseUrl": "https://your-app.test",
  "laravelQueue": "scrapers",
  "correlationId": "job-uuid-from-laravel",
  "waitForFinish": true,
  "waitSecs": 120,
  "pushResultsToLaravel": true,
  "callbackOnProgress": true,
  "mergeProxyIntoTargetActor": false,
  "maxRetries": 3
}
````

Health-check example (Apify Console Try actor):

```json
{
  "runHealthCheckOnStart": true
}
```

Integration trigger example (static Laravel config; `payload` attached automatically):

```json
{
  "mode": "process_trigger",
  "laravelWebhookUrl": "https://your-app.test/api/apify/webhook",
  "laravelQueue": "default",
  "pushResultsToLaravel": true,
  "callbackOnProgress": true
}
```

- **`runHealthCheckOnStart`** (optional): If `true`, writes one demo dataset row and exits (default `false`). Use for Apify Console health checks.
- **`mode`** (optional): `run_actor` | `process_trigger` | `forward_dataset` (default `run_actor`).
- **`laravelWebhookUrl`** (optional): HTTPS endpoint on your Laravel app for run progress and completion callbacks.
- **`laravelWebhookSecret`** (optional): Shared secret for `X-Apify-Signature` (HMAC SHA-256). **Secret input** — encrypted at rest, not copied to dataset rows.
- **`laravelApiToken`** (optional): Bearer token sent as `Authorization` when calling your Laravel webhook. **Secret input**.
- **`laravelBaseUrl`** (optional): Base URL of your Laravel app (included in callback payloads for traceability).
- **`laravelQueue`** (optional): Queue name your Laravel app should use when dispatching jobs from the webhook (default `default`).
- **`correlationId`** (optional): ID from your Laravel request/job so callbacks can be matched to the originating job.
- **`targetActorId`** (required when `mode=run_actor`): Apify Actor ID or `username/actor-name` to run (e.g. `sovanza.inc/python-scraper`).
- **`startUrls`** (optional shortcut): Top-level URLs merged into `targetActorInput.startUrls` for python-scraper.
- **`targetActorInput`** (optional): JSON object passed to the target Actor (scraper parameters from Laravel).
- **`waitForFinish`** (optional): If `true`, blocks until the target Actor run completes (default `true`).
- **`waitSecs`** (optional): Max seconds to wait for the target Actor when `waitForFinish` is true (default `300`, max `3600`).
- **`mergeProxyIntoTargetActor`** (optional): Inject `proxyConfiguration` into `targetActorInput` when not already set (default `true`).
- **`proxyConfiguration`** (optional): Apify proxy settings; forwarded to child Actors when merging is enabled.
- **`maxRetries`** (optional): Retry count for Actor calls and Laravel webhook requests (default `3`).
- **`retryDelayMs`** (optional): Base delay between retries in ms (default `1000`).
- **`pushResultsToLaravel`** (optional): Send final `SUCCEEDED` callback when the run completes (default `true`).
- **`callbackOnProgress`** (optional): Send `STARTED` / `PROCESSING` callbacks during long operations (default `true`).
- **`includeDatasetPreviewInCallback`** (optional): Attach up to `maxCallbackItems` rows in the final callback (default `false`).
- **`maxCallbackItems`** (optional): Max dataset rows in callback preview (default `50`).
- **`maxDatasetItems`** (optional): Max source dataset rows to process in `process_trigger` mode (default `1000`).
- **`datasetBatchSize`** (optional): Batch size when reading source datasets (default `100`).
- **`sourceDatasetId`** (advanced): Override dataset ID; when empty, reads `payload.resource.defaultDatasetId`.
- **`sourceKeyValueStoreId`** (advanced): Override KV store ID from trigger payload.
- **`sourceRunId`** (advanced): Override triggering run ID from trigger payload.
- **`payload`** (automatic): Attached by Apify when started via Actor integrations or `isApifyIntegration` webhooks.

##### Authentication & sensitive input

Fields that can hold credentials use Apify **secret input** (`isSecret: true`), following the same pattern as other CloudBots Actors:

- **`laravelWebhookSecret`** — shared HMAC secret for webhook verification
- **`laravelApiToken`** — Bearer token for your Laravel API

Secret values are encrypted in storage and are **not** written into dataset rows or logs.

##### Static vs dynamic input (integration-ready)

Per [Apify integration guidelines](https://docs.apify.com/platform/integrations/actors/integration-ready-actors):

- **Static input** — Laravel webhook URL, secrets, queue, target Actor config (same value every run).
- **Dynamic input** — dataset ID, run ID, KV store ID from the triggering event (read from `payload.resource`).

When chained via **Integrations → Connect Actor**, Apify attaches:

```json
{
  "payload": {
    "eventType": "ACTOR.RUN.SUCCEEDED",
    "resource": {
      "id": "runId...",
      "defaultDatasetId": "datasetId...",
      "defaultKeyValueStoreId": "kvId...",
      "status": "SUCCEEDED"
    }
  }
}
```

Recommended integration prefill (Apify Console → Actor → Settings → Integrations): see `INTEGRATION_INPUT.example.json`.

##### Apify Console (quality score & monetization)

After deploying build **0.1+**, finish these in **Apify Console → Publication** (cannot be set in git):

1. **Monetization → Pay per event (PPE)** or pay-per-usage — tune based on your CU cost for child Actor calls.
2. **Store discounts:** enable tier discounts for Bronze, Silver, and Gold plans.
3. Re-run **Try actor** with `runHealthCheckOnStart: true` — should finish in under 2 minutes on Apify.

##### Environment variables (optional)

| Variable | Purpose |
|----------|---------|
| `APIFY_TOKEN` | Required on Apify platform; used by `Actor.call()` and dataset API access for child Actors. |
| `APIFY_LOG_LEVEL` | Logging verbosity (default `INFO` in `apify.json`). |

##### Run locally

`INPUT.json` is gitignored. Copy `INPUT.example.json` to `INPUT.json`, set `APIFY_TOKEN`, then:

```bash
cd laravel-integration
npm install
cp INPUT.example.json INPUT.json
npm run validate
node src/main.js
```

Push to Apify:

```bash
apify push
```

### Output

Results are stored in the Actor's **default dataset**. Each run produces summary rows and, in `process_trigger` mode, copied data rows.

Typical fields (when data is available):

- **Summary:** `type` (`health_check`, `__summary__`, `__error__`), `mode`, `success`, `timestamp`, `message`, `error`.
- **Child Actor run:** `targetActorId`, `runId`, `status`, `defaultDatasetId`, `defaultKeyValueStoreId`, `itemCount`.
- **Trigger processing:** `sourceDatasetId`, `sourceRunId`, `outputDatasetId`, `processedItems`.
- **Copied rows:** original dataset fields plus `__sourceDatasetId`, `__sourceRunId` metadata.

Example summary item (illustrative):

```json
{
  "type": "__summary__",
  "mode": "run_actor",
  "success": true,
  "targetActorId": "YOUR_USERNAME/instagram-reels-scraper",
  "runId": "abc123runId",
  "status": "SUCCEEDED",
  "defaultDatasetId": "xyz789datasetId",
  "itemCount": 5,
  "timestamp": "2026-06-04T12:00:00.000Z"
}
```

Example Laravel callback payload (sent to your webhook, not stored in dataset unless you log it):

```json
{
  "service": "laravel-integration",
  "status": "SUCCEEDED",
  "phase": "completed",
  "correlationId": "uuid-from-laravel",
  "laravelQueue": "scrapers",
  "mode": "run_actor",
  "targetActorId": "YOUR_USERNAME/instagram-reels-scraper",
  "runId": "childRunId",
  "defaultDatasetId": "resultDatasetId",
  "itemCount": 10,
  "apifyDatasetUrl": "https://api.apify.com/v2/datasets/.../items",
  "timestamp": "2026-06-04T12:00:00.000Z"
}
```

➡️ Output is structured for Laravel jobs, warehouses, or spreadsheet export via Apify.

### Use Cases

- **Laravel scraping APIs:** expose `POST /api/scrape/...` endpoints that start Apify runs and return run/dataset IDs.
- **Queued job pipelines:** receive webhooks in Laravel, dispatch jobs to `laravelQueue`, pull dataset items asynchronously.
- **Actor chaining:** when a scraper finishes, automatically process or forward its default dataset to your app.
- **Multi-tenant SaaS:** pass `correlationId` per customer request and route callbacks to the correct tenant handler.

### Integrations & API

- Run and fetch results through the **Apify API**
- Call from **Laravel** using `apify/apify-client` (see `routes/laravel_integration.example.php`)
- Connect **Zapier**, **Make**, **Google Sheets**, and other Apify integrations
- **Webhooks** and **schedules** for recurring automation
- Chain Actors via **Integrations → Connect Actor** with `isApifyIntegration` webhooks

#### Laravel example (PHP)

Install the official client:

```bash
composer require apify/apify-client
```

Call this Actor from Laravel:

```php
use Apify\Client\ApifyClient;

$client = new ApifyClient(['token' => env('APIFY_TOKEN')]);

$run = $client->actor('YOUR_USERNAME/laravel-integration')->call([
    'mode' => 'run_actor',
    'targetActorId' => 'YOUR_USERNAME/instagram-reels-scraper',
    'targetActorInput' => [
        'usernames' => ['https://www.instagram.com/nasa/'],
        'resultsLimit' => 10,
    ],
    'laravelWebhookUrl' => route('apify.webhook'),
    'laravelWebhookSecret' => env('APIFY_WEBHOOK_SECRET'),
    'correlationId' => (string) Str::uuid(),
    'waitForFinish' => false,
]);
```

Webhook handler (verify signature):

```php
public function handle(Request $request)
{
    $body = $request->getContent();
    $expected = hash_hmac('sha256', $body, env('APIFY_WEBHOOK_SECRET'));
    abort_unless(hash_equals($expected, $request->header('X-Apify-Signature', '')), 401);

    $payload = json_decode($body, true);
    // status: STARTED | PROCESSING | SUCCEEDED | FAILED | DATASET_READY
}
```

#### Setting up Actor integration (webhook chain)

1. Open your scraper Actor → **Integrations** → **Connect Actor**
2. Select **laravel-integration**
3. Event: **Run succeeded**
4. Static input: Laravel webhook URL, queue, secrets
5. Apify prefills dynamic fields from `{{resource.defaultDatasetId}}` via `payload`

See [Integrating Actors via API](https://docs.apify.com/platform/integrations/actors/integrating-actors-via-api).

### Why Choose This Actor?

- **Integration-ready** — reads `payload.resource.defaultDatasetId` automatically per Apify guidelines
- **Laravel-first callbacks** — HMAC signatures, queue hints, correlation IDs
- **Run any scraper** — one stable integration Actor instead of custom glue per scraper
- **Proxy + retries** — production patterns reused from CloudBots scraper actors
- Built for **Apify** datasets, exports, API access, and Actor chaining

### FAQ

#### How does Laravel Integration work?

Your Laravel app starts this Actor with static config and scraper parameters. The Actor calls child Apify Actors via `Actor.call()`, processes integration trigger datasets in batches, or forwards dataset metadata to your Laravel webhook. Progress and completion are reported via HTTPS POST callbacks.

#### Can I call scrapers directly from Laravel without this Actor?

Yes. This Actor adds standardized integration trigger handling, webhook callbacks, proxy merging, retries, and dataset batch processing in one reusable place.

#### Does the webhook include all scraped data?

No. By design, Apify integrations pass **dataset IDs**, not full dataset contents. Enable `includeDatasetPreviewInCallback` for a limited preview; otherwise pull items via the Apify API in your Laravel job.

#### What is the difference between static and dynamic input?

Static input (webhook URL, secrets, queue) stays the same across runs. Dynamic input (dataset ID, run ID) comes from the integration trigger `payload` field automatically when you connect this Actor on another Actor's Integrations tab.

#### Can I use this without Laravel?

Yes. Any HTTPS endpoint can receive callbacks; Laravel-specific fields (`laravelQueue`, `laravelBaseUrl`) are optional metadata.

#### What integration modes are available?

- **`run_actor`** — start a child scraper with `targetActorId` + `targetActorInput`
- **`process_trigger`** — copy rows from a trigger dataset into this run's dataset
- **`forward_dataset`** — POST dataset metadata to your Laravel webhook

#### Why did run\_actor fail with "does not support running public Actors"?

Some Apify plans cannot call Store/public Actors like `apify/hello-world`. Options:

- Set **`runHealthCheckOnStart: true`** for a quick smoke test (no child Actor).
- Keep **`useDemoFallbackOnPublicActorError: true`** (default) — the Actor writes a demo result row instead of failing.
- In production, set **`targetActorId`** to **your own** Actor (e.g. `YOUR_USERNAME/instagram-reels-scraper`).

#### What formats can I download?

**JSON**, **CSV**, and **Excel** from the Apify dataset UI, plus full access via the **Apify API**.

### SEO Keywords

laravel apify integration\
apify laravel webhook\
laravel scraping api\
apify actor integration\
laravel automation apify\
php apify client\
web scraping laravel\
apify integration actor\
laravel queue webhook\
apify dataset callback

### Actor permissions

This Actor is intended to work with **limited permissions**: it reads your input, calls other Actors you specify, reads datasets by ID, and writes to its **default dataset**. It posts callbacks only to URLs you provide.

**To set limited permissions in Apify Console:**

1. Open your Actor on the Apify platform.
2. Go to **Source** or **Settings**.
3. Open **Review permissions** / **Permissions**.
4. Choose **Limited permissions** and save.

### Limitations

- Child Actor runs consume your Apify platform credits and depend on the target Actor's reliability.
- `waitSecs` caps how long this Actor waits for a child run; very long scrapes may need `waitForFinish: false` and webhook-based completion handling in Laravel.
- Webhook delivery requires your Laravel endpoint to be reachable from Apify cloud.
- Dataset preview in callbacks is limited by `maxCallbackItems`; large datasets should be fetched via the Apify API in Laravel.
- This Actor orchestrates integration — it does not scrape websites directly unless configured to call a scraper Actor.

### License

This project is licensed under the MIT License - see the LICENSE file for details.

### Get Started

Configure your Laravel webhook URL, set `mode=run_actor` with a target scraper, enable proxy if needed, and start your first run on Apify — or connect this Actor on another Actor's **Integrations** tab to chain scrapers automatically. 🚀

# Actor input Schema

## `runHealthCheckOnStart` (type: `boolean`):

If true, writes one demo dataset row and exits (Apify Console Try actor / CI validation). If false, executes the selected integration mode.

## `mode` (type: `string`):

run\_actor: call another Apify Actor with parameters from Laravel. process\_trigger: read dataset items from an integration trigger payload and copy them to this run's dataset. forward\_dataset: POST dataset metadata (and optional preview) to your Laravel webhook.

## `laravelWebhookUrl` (type: `string`):

HTTPS endpoint on your Laravel app that receives run progress and completion callbacks (e.g. https://your-app.test/api/apify/webhook).

## `laravelBaseUrl` (type: `string`):

Base URL of your Laravel application (included in callback payloads for traceability).

## `laravelQueue` (type: `string`):

Queue connection name your Laravel app should use when dispatching jobs from the webhook (passed in callback payload).

## `correlationId` (type: `string`):

Optional ID from your Laravel request/job so callbacks can be matched to the originating job.

## `targetActorId` (type: `string`):

Apify Actor ID or username/actor-name to run when mode=run\_actor (e.g. sovanza.inc/python-scraper or YOUR\_USER/my-scraper).

## `startUrls` (type: `array`):

Shortcut for python-scraper when mode=run\_actor. Merged into targetActorInput.startUrls. No cookies required.

## `targetActorInput` (type: `object`):

Full input object passed to the target Actor. Default targets python-scraper (startUrls). For other Actors put their required fields here or use top-level shortcut fields.

## `waitForFinish` (type: `boolean`):

If true, blocks until the target Actor run completes (up to waitSecs). If false, starts the run and returns immediately.

## `waitSecs` (type: `integer`):

Maximum seconds to wait for the target Actor when waitForFinish is true.

## `pushResultsToLaravel` (type: `boolean`):

Send a final SUCCEEDED callback to laravelWebhookUrl when the run completes successfully.

## `callbackOnProgress` (type: `boolean`):

Send STARTED/PROCESSING callbacks during long operations.

## `includeDatasetPreviewInCallback` (type: `boolean`):

Attach up to maxCallbackItems rows from the result dataset in the final Laravel callback.

## `maxCallbackItems` (type: `integer`):

Maximum dataset rows to include in Laravel callback payloads when preview is enabled.

## `maxDatasetItems` (type: `integer`):

When mode=process\_trigger, maximum number of source dataset rows to read and copy.

## `datasetBatchSize` (type: `integer`):

Number of dataset items fetched per batch when processing trigger datasets.

## `mergeProxyIntoTargetActor` (type: `boolean`):

If true and proxyConfiguration is set, injects it into targetActorInput when the target input does not already define proxyConfiguration.

## `useDemoFallbackOnPublicActorError` (type: `boolean`):

If true and Actor.call fails because your Apify plan cannot run public Actors (e.g. apify/hello-world), writes a demo result row instead of failing. Use your own username/actor-name in production.

## `maxRetries` (type: `integer`):

Retry count for Actor calls and Laravel webhook requests.

## `retryDelayMs` (type: `integer`):

Base delay between retries (multiplied by attempt number).

## `sourceDatasetId` (type: `string`):

Override dataset ID. When empty, the Actor reads payload.resource.defaultDatasetId from Apify integration triggers automatically.

## `sourceKeyValueStoreId` (type: `string`):

Override KV store ID from trigger payload (payload.resource.defaultKeyValueStoreId).

## `sourceRunId` (type: `string`):

Override triggering run ID (payload.resource.id).

## `laravelWebhookSecret` (type: `string`):

Shared secret used to sign callbacks with X-Apify-Signature (HMAC SHA-256). Store the same value in Laravel as APIFY\_WEBHOOK\_SECRET. Stored as a secret input and never written to the dataset.

## `laravelApiToken` (type: `string`):

Optional Bearer token sent as Authorization header when calling your Laravel webhook. Stored as a secret input.

## `proxyConfiguration` (type: `object`):

Apify proxy settings forwarded to child Actors when mergeProxyIntoTargetActor is enabled.

## Actor input object example

```json
{
  "runHealthCheckOnStart": true,
  "mode": "run_actor",
  "laravelBaseUrl": "https://your-app.test",
  "laravelQueue": "default",
  "targetActorId": "sovanza.inc/python-scraper",
  "startUrls": [
    "https://example.com"
  ],
  "targetActorInput": {
    "startUrls": [
      "https://example.com"
    ],
    "includeLinks": true,
    "includeHtml": false,
    "exportFormat": "json"
  },
  "waitForFinish": true,
  "waitSecs": 300,
  "pushResultsToLaravel": true,
  "callbackOnProgress": true,
  "includeDatasetPreviewInCallback": false,
  "maxCallbackItems": 50,
  "maxDatasetItems": 100,
  "datasetBatchSize": 100,
  "mergeProxyIntoTargetActor": true,
  "useDemoFallbackOnPublicActorError": true,
  "maxRetries": 3,
  "retryDelayMs": 1000,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

## `integrations` (type: `string`):

Laravel integration results in the default dataset.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "runHealthCheckOnStart": true,
    "mode": "run_actor",
    "laravelWebhookUrl": "",
    "laravelBaseUrl": "https://your-app.test",
    "laravelQueue": "default",
    "correlationId": "",
    "targetActorId": "sovanza.inc/python-scraper",
    "startUrls": [
        "https://example.com"
    ],
    "targetActorInput": {
        "startUrls": [
            "https://example.com"
        ],
        "includeLinks": true,
        "includeHtml": false,
        "exportFormat": "json"
    },
    "waitSecs": 300,
    "maxCallbackItems": 50,
    "maxDatasetItems": 100,
    "datasetBatchSize": 100,
    "useDemoFallbackOnPublicActorError": true,
    "maxRetries": 3,
    "retryDelayMs": 1000,
    "sourceDatasetId": "",
    "sourceKeyValueStoreId": "",
    "sourceRunId": "",
    "laravelWebhookSecret": "",
    "laravelApiToken": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("sovanza.inc/laravel-integration").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "runHealthCheckOnStart": True,
    "mode": "run_actor",
    "laravelWebhookUrl": "",
    "laravelBaseUrl": "https://your-app.test",
    "laravelQueue": "default",
    "correlationId": "",
    "targetActorId": "sovanza.inc/python-scraper",
    "startUrls": ["https://example.com"],
    "targetActorInput": {
        "startUrls": ["https://example.com"],
        "includeLinks": True,
        "includeHtml": False,
        "exportFormat": "json",
    },
    "waitSecs": 300,
    "maxCallbackItems": 50,
    "maxDatasetItems": 100,
    "datasetBatchSize": 100,
    "useDemoFallbackOnPublicActorError": True,
    "maxRetries": 3,
    "retryDelayMs": 1000,
    "sourceDatasetId": "",
    "sourceKeyValueStoreId": "",
    "sourceRunId": "",
    "laravelWebhookSecret": "",
    "laravelApiToken": "",
}

# Run the Actor and wait for it to finish
run = client.actor("sovanza.inc/laravel-integration").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "runHealthCheckOnStart": true,
  "mode": "run_actor",
  "laravelWebhookUrl": "",
  "laravelBaseUrl": "https://your-app.test",
  "laravelQueue": "default",
  "correlationId": "",
  "targetActorId": "sovanza.inc/python-scraper",
  "startUrls": [
    "https://example.com"
  ],
  "targetActorInput": {
    "startUrls": [
      "https://example.com"
    ],
    "includeLinks": true,
    "includeHtml": false,
    "exportFormat": "json"
  },
  "waitSecs": 300,
  "maxCallbackItems": 50,
  "maxDatasetItems": 100,
  "datasetBatchSize": 100,
  "useDemoFallbackOnPublicActorError": true,
  "maxRetries": 3,
  "retryDelayMs": 1000,
  "sourceDatasetId": "",
  "sourceKeyValueStoreId": "",
  "sourceRunId": "",
  "laravelWebhookSecret": "",
  "laravelApiToken": ""
}' |
apify call sovanza.inc/laravel-integration --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=sovanza.inc/laravel-integration",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Laravel Integration",
        "description": "Laravel Integration connects Laravel apps with Apify to run Actors, process trigger datasets, send signed webhook callbacks, forward dataset IDs, and support scraper orchestration, queue workflows, and Actor chaining.",
        "version": "0.0",
        "x-build-id": "QNnjjOIhdkQWrKnUe"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/sovanza.inc~laravel-integration/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-sovanza.inc-laravel-integration",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/sovanza.inc~laravel-integration/runs": {
            "post": {
                "operationId": "runs-sync-sovanza.inc-laravel-integration",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/sovanza.inc~laravel-integration/run-sync": {
            "post": {
                "operationId": "run-sync-sovanza.inc-laravel-integration",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "runHealthCheckOnStart": {
                        "title": "Run health-check demo on start",
                        "type": "boolean",
                        "description": "If true, writes one demo dataset row and exits (Apify Console Try actor / CI validation). If false, executes the selected integration mode.",
                        "default": false
                    },
                    "mode": {
                        "title": "Integration mode",
                        "enum": [
                            "run_actor",
                            "process_trigger",
                            "forward_dataset"
                        ],
                        "type": "string",
                        "description": "run_actor: call another Apify Actor with parameters from Laravel. process_trigger: read dataset items from an integration trigger payload and copy them to this run's dataset. forward_dataset: POST dataset metadata (and optional preview) to your Laravel webhook.",
                        "default": "run_actor"
                    },
                    "laravelWebhookUrl": {
                        "title": "Laravel webhook URL",
                        "type": "string",
                        "description": "HTTPS endpoint on your Laravel app that receives run progress and completion callbacks (e.g. https://your-app.test/api/apify/webhook)."
                    },
                    "laravelBaseUrl": {
                        "title": "Laravel base URL",
                        "type": "string",
                        "description": "Base URL of your Laravel application (included in callback payloads for traceability)."
                    },
                    "laravelQueue": {
                        "title": "Laravel queue name",
                        "type": "string",
                        "description": "Queue connection name your Laravel app should use when dispatching jobs from the webhook (passed in callback payload).",
                        "default": "default"
                    },
                    "correlationId": {
                        "title": "Correlation ID",
                        "type": "string",
                        "description": "Optional ID from your Laravel request/job so callbacks can be matched to the originating job."
                    },
                    "targetActorId": {
                        "title": "Target Actor ID",
                        "type": "string",
                        "description": "Apify Actor ID or username/actor-name to run when mode=run_actor (e.g. sovanza.inc/python-scraper or YOUR_USER/my-scraper)."
                    },
                    "startUrls": {
                        "title": "Start URLs (shortcut)",
                        "type": "array",
                        "description": "Shortcut for python-scraper when mode=run_actor. Merged into targetActorInput.startUrls. No cookies required.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "targetActorInput": {
                        "title": "Target Actor input (JSON)",
                        "type": "object",
                        "description": "Full input object passed to the target Actor. Default targets python-scraper (startUrls). For other Actors put their required fields here or use top-level shortcut fields."
                    },
                    "waitForFinish": {
                        "title": "Wait for target Actor to finish",
                        "type": "boolean",
                        "description": "If true, blocks until the target Actor run completes (up to waitSecs). If false, starts the run and returns immediately.",
                        "default": true
                    },
                    "waitSecs": {
                        "title": "Wait timeout (seconds)",
                        "minimum": 0,
                        "maximum": 3600,
                        "type": "integer",
                        "description": "Maximum seconds to wait for the target Actor when waitForFinish is true.",
                        "default": 300
                    },
                    "pushResultsToLaravel": {
                        "title": "Push final results to Laravel",
                        "type": "boolean",
                        "description": "Send a final SUCCEEDED callback to laravelWebhookUrl when the run completes successfully.",
                        "default": true
                    },
                    "callbackOnProgress": {
                        "title": "Callback on progress",
                        "type": "boolean",
                        "description": "Send STARTED/PROCESSING callbacks during long operations.",
                        "default": true
                    },
                    "includeDatasetPreviewInCallback": {
                        "title": "Include dataset preview in callback",
                        "type": "boolean",
                        "description": "Attach up to maxCallbackItems rows from the result dataset in the final Laravel callback.",
                        "default": false
                    },
                    "maxCallbackItems": {
                        "title": "Max items in callback preview",
                        "minimum": 0,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Maximum dataset rows to include in Laravel callback payloads when preview is enabled.",
                        "default": 50
                    },
                    "maxDatasetItems": {
                        "title": "Max dataset items to process",
                        "minimum": 1,
                        "maximum": 100000,
                        "type": "integer",
                        "description": "When mode=process_trigger, maximum number of source dataset rows to read and copy.",
                        "default": 1000
                    },
                    "datasetBatchSize": {
                        "title": "Dataset batch size",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Number of dataset items fetched per batch when processing trigger datasets.",
                        "default": 100
                    },
                    "mergeProxyIntoTargetActor": {
                        "title": "Merge proxy into target Actor input",
                        "type": "boolean",
                        "description": "If true and proxyConfiguration is set, injects it into targetActorInput when the target input does not already define proxyConfiguration.",
                        "default": true
                    },
                    "useDemoFallbackOnPublicActorError": {
                        "title": "Demo fallback when public Actors are disabled",
                        "type": "boolean",
                        "description": "If true and Actor.call fails because your Apify plan cannot run public Actors (e.g. apify/hello-world), writes a demo result row instead of failing. Use your own username/actor-name in production.",
                        "default": true
                    },
                    "maxRetries": {
                        "title": "Max retries",
                        "minimum": 1,
                        "maximum": 10,
                        "type": "integer",
                        "description": "Retry count for Actor calls and Laravel webhook requests.",
                        "default": 3
                    },
                    "retryDelayMs": {
                        "title": "Retry delay (ms)",
                        "minimum": 100,
                        "maximum": 60000,
                        "type": "integer",
                        "description": "Base delay between retries (multiplied by attempt number).",
                        "default": 1000
                    },
                    "sourceDatasetId": {
                        "title": "Source dataset ID (advanced)",
                        "type": "string",
                        "description": "Override dataset ID. When empty, the Actor reads payload.resource.defaultDatasetId from Apify integration triggers automatically."
                    },
                    "sourceKeyValueStoreId": {
                        "title": "Source key-value store ID (advanced)",
                        "type": "string",
                        "description": "Override KV store ID from trigger payload (payload.resource.defaultKeyValueStoreId)."
                    },
                    "sourceRunId": {
                        "title": "Source run ID (advanced)",
                        "type": "string",
                        "description": "Override triggering run ID (payload.resource.id)."
                    },
                    "laravelWebhookSecret": {
                        "title": "Laravel webhook secret (optional)",
                        "type": "string",
                        "description": "Shared secret used to sign callbacks with X-Apify-Signature (HMAC SHA-256). Store the same value in Laravel as APIFY_WEBHOOK_SECRET. Stored as a secret input and never written to the dataset."
                    },
                    "laravelApiToken": {
                        "title": "Laravel API token (optional)",
                        "type": "string",
                        "description": "Optional Bearer token sent as Authorization header when calling your Laravel webhook. Stored as a secret input."
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Apify proxy settings forwarded to child Actors when mergeProxyIntoTargetActor is enabled.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ],
                            "apifyProxyCountry": "US"
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
