---
name: memeperfect-agent
description: Use this skill when an agent needs to create, update, activate, inspect, or integrate MemePerfect Strategies through the public external API. This skill is restricted to documented external API capabilities and should not assume access to UI-only features.
license: MIT
compatibility: Requires HTTPS requests to the MemePerfect external API and a valid API key from the MemePerfect app.
metadata:
  author: MemePerfect
  version: "1.0"
---

## Capabilities

MemePerfect helps users build automated token discovery Strategies that combine on-chain security analysis, market metrics, social signals, and AI-powered narrative detection.

From an agent perspective, the important distinction is:

- the product has broader UI capabilities and workflows
- this skill only authorizes actions that are documented in the public external API

MemePerfect exposes a public external API for:

- reading authenticated account limits
- creating and listing Strategies
- updating, activating, deactivating, and deleting Strategies
- reading notifications and performance summaries
- reading persisted Strategy evaluations
- creating, listing, polling, and inspecting Backtest jobs
- reading tracked Twitter handles and Twitter tags
- reading and managing followed developer wallets and developer tags
- configuring outbound webhooks

Agents should treat this file as the source of truth for what is supported through the public API.

## Product context

Use this context to reason about user intent and payload design:

- `Strategy` is the main object that combines triggers, rules, and delivery behavior
- `Trigger` defines when a Strategy runs
- `Dealbreakers` are hard-fail checks that block alerts before grouped rules are evaluated
- `Rules` are the conditional checks inside rule groups
- `Flexible Matching` allows partial rule matches when enabled
- `Backtests`, `Watchlist`, `Twitter Handles`, `Dev Tracking`, and `AI Narrative Engine` are product concepts that may appear in docs and user requests

This context helps the agent understand the platform, but it does not expand the public API surface.

## Skills

These describe what the product is designed to do. Only use them as reasoning context unless a matching external API endpoint is documented below.

### Strategy building and automation

**Create custom Strategies**: Build multi-layered token discovery Strategies that combine event-driven Triggers with rule-based evaluation.

**Flexible Matching**: Use percentage-based matching to allow a Strategy to pass when a defined portion of grouped rules are satisfied.

**Strict mode**: Require more complete input data during evaluation.

**Cooldown control**: Suppress repeated alerts for the same token with `alertCooldownMins`.

### Trigger types

These concepts map to documented `eventType` values:

**New token created**: Evaluate newly launched tokens.

**Token graduation events**: Evaluate tokens reaching later lifecycle states.

**Tweet mentions**: Evaluate tokens when tracked tweet data matches direct mentions.

**AI-generated narratives**: Evaluate tokens against narrative-derived matches from tweet metadata.

**Developer tracking**: Evaluate tokens launched by followed developers when that trigger is used.

### Evaluation dimensions

Strategies usually evaluate across four fixed rule-group dimensions:

**Security**: Contract safety, ownership concentration, creator history, LP state, token age.

**Market**: Liquidity, market cap, taxes, trading activity, holder count.

**Socials**: Website, Telegram, Twitter/X, social presence, link-content checks.

**AI**: Content validation scores derived from website or X content.

## Inputs required

To act successfully, an agent needs:

- `base_url`: `https://api.memeperfect.io/api/external/v1`
- `api_key`: read from `MEMEPERFECT_API_KEY`, then sent as `X-API-Key` or `Authorization: ApiKey ...`
- a valid Strategy payload when creating or updating a Strategy
- a webhook URL when configuring webhook delivery

## Credential preflight

Before making any API call, confirm that a MemePerfect API key is available without exposing it.

Credential lookup order:

1. Read `MEMEPERFECT_API_KEY` from the current process environment.
2. If the environment variable is missing and the runtime supports local files, check a local `.env` file in the current working directory for `MEMEPERFECT_API_KEY`.
3. If the key is still missing, stop and ask the user to set `MEMEPERFECT_API_KEY` in their environment or local `.env` file. Do not ask the user to paste the key into chat.

Safe local setup examples:

```bash
read -s MEMEPERFECT_API_KEY
export MEMEPERFECT_API_KEY
```

```bash
printf 'MEMEPERFECT_API_KEY=mpk_your_key_here\n' > .env
chmod 600 .env
```

Security rules:

- never print, log, summarize, or echo the API key
- never place the key in a URL, browser code, client-side bundle, screenshot, or committed file
- never include a placeholder key in a real API request
- use the key only in request headers
- prefer `X-API-Key: $MEMEPERFECT_API_KEY`

## Authentication and limits

Use one of these headers:

```http
X-API-Key: mpk_your_api_key_here
```

```http
Authorization: ApiKey mpk_your_api_key_here
```

Check limits with `GET /me`.

Typical plan limits:

- `PRO`: 60 requests per minute, up to 25 active Strategies, 25 Backtests per UTC day, 7-day Backtest lookback
- `DEGEN`: 300 requests per minute, up to 50 active Strategies, unlimited daily Backtests, 14-day Backtest lookback

## Supported endpoints

Use only these documented endpoint families:

- `GET /me`
- `GET /strategies`
- `POST /strategies`
- `GET /strategies/:id`
- `PATCH /strategies/:id`
- `POST /strategies/:id/activate`
- `POST /strategies/:id/deactivate`
- `DELETE /strategies/:id`
- `GET /notifications`
- `GET /notifications/:id`
- `GET /notifications/performance`
- `GET /notifications/performance/last`
- `POST /notifications/performance/jobs`
- `GET /notifications/performance/jobs/:jobId`
- `GET /strategy-evaluations`
- `GET /backtests`
- `POST /backtests`
- `GET /backtests/:id`
- `GET /backtests/:id/results`
- `GET /twitter/handles`
- `GET /twitter/tags`
- `GET /devs/my`
- `GET /devs/tags`
- `GET /devs/:address/tags`
- `POST /devs/:address/add`
- `PUT /devs/:address/update`
- `PUT /devs/:address/tags`
- `PATCH /devs/tags/:id`
- `DELETE /devs/tags/:id`
- `GET /webhook`
- `PUT /webhook`

Do not assume app-only endpoints are available through the public API. Manual
single-token Strategy Test runs, including live/backtest source selection, are
JWT-authenticated app functionality. Public API integrations should use the
async `/backtests` workflow for historical testing.

## Strategy payload rules

When creating or updating Strategies, preserve these product terms exactly:

- `Strategy`
- `Trigger`
- `Rules`
- `Dealbreakers`
- `Flexible Matching`
- `Backtests`
- `Watchlist`
- `Twitter Handles`
- `Dev Tracking`
- `AI Narrative Engine`

For API payloads:

- `triggers`, `rules`, and `isActive` are core Strategy create/update fields
- `triggers` is an array of event type strings; do not send internal trigger objects
- `triggerConfigs` is the external per-trigger configuration map
- for `twitter_mention_direct` and `tweet_metadata_match`, send `triggerConfigs.<eventType>.tagId`
- for `followed_dev_new_token_created`, send `triggerConfigs.followed_dev_new_token_created.scope` as `"all"`, `"tag"`, or `"wallet"`
- for followed-dev `scope: "tag"`, include a user-owned dev `tagId` from `GET /devs/tags`
- for followed-dev `scope: "wallet"`, include `developerAddress` for a wallet in the followed developers list
- omitting `triggerConfigs.followed_dev_new_token_created` evaluates against all active followed developers
- `rules` is a flat external rule list; the backend maps rules into internal Dealbreakers and rule groups
- object-style rules use `config` for advanced volume/activity and wallet-quality checks
- coordinated wallet cluster checks use `clusterConfig`
- `strict` is optional and controls data strictness
- `alertCooldownMins` is optional and suppresses repeat alerts for the same token within the cooldown window
- `retryPolicy` is optional for strategy-level retry behavior when supported by the API
- `matching.enabled` and `matching.minPercent` control Flexible Matching behavior

## Strategy payload format

Use this as the canonical create/update shape:

```json
{
  "name": "API Strategy Example",
  "description": "Programmatic strategy",
  "strict": true,
  "alertCooldownMins": 30,
  "retryPolicy": {
    "type": "QUICK_RETRY",
    "maxAttempts": 3,
    "delayMinutes": 15
  },
  "matching": {
    "enabled": true,
    "minPercent": 80
  },
  "triggers": ["new_token_created"],
  "rules": [
    {
      "rule": "is_honeypot",
      "dealbreaker": true,
      "enabled": true
    },
    {
      "rule": "market_cap",
      "dealbreaker": true,
      "min": 2500,
      "max": 180000
    },
    {
      "rule": "risk_level",
      "dealbreaker": false,
      "value": "LOW"
    },
    {
      "rule": "liquidity_usd",
      "dealbreaker": false,
      "min": 3000
    },
    {
      "rule": "volume_24h",
      "dealbreaker": false,
      "config": {
        "windows": {
          "5m": 5000,
          "1h": 10000,
          "6h": 25000,
          "24h": 50000
        }
      }
    },
    {
      "rule": "quality_wallet_count",
      "dealbreaker": false,
      "config": {
        "minWallets": 5,
        "walletTypes": ["smart_wallet", "kol", "whale", "profitable_trader"]
      }
    },
    {
      "rule": "coordinated_wallet_cluster",
      "dealbreaker": false,
      "clusterConfig": {
        "maxTotalHeldPct": 20,
        "maxSingleClusterPct": 10,
        "maxClusterRisk": "high"
      }
    }
  ],
  "isActive": false
}
```

Field notes:

- `name`: required string
- `description`: optional string
- `strict`: optional boolean
- `alertCooldownMins`: optional number from `0` to `1440`
- `matching.enabled`: optional boolean
- `matching.minPercent`: required when matching is enabled
- `triggers`: required array of event type strings such as `"new_token_created"`
- `rules`: required flat array of external rule objects
- `isActive`: optional boolean on create; defaults to `false` when omitted
- `dealbreakers` and `ruleGroups`: returned by read endpoints, but do not send them to create/update endpoints
- wallet-quality and coordinated wallet cluster rules use API-backed third-party data and cannot be submitted as Dealbreakers

## Backtest payload rules

Use Backtests to replay one of the authenticated user's Strategies against recent stored token observations.

Backtest behavior:

- Backtests are asynchronous jobs.
- `POST /backtests` returns a queued job; poll `GET /backtests/:id`.
- Results are available from `GET /backtests/:id/results`.
- The API stores a Strategy snapshot when the job is created, so later Strategy edits do not change that backtest run.
- Missing or cross-user Backtest IDs return `404`.

Strategy evaluation list pagination:

- `GET /strategy-evaluations` accepts `pageSize` and `limit`; `limit` is a compatibility alias and `pageSize` wins when both are sent.
- Responses return `total: null`, `hasMore`, and `nextCursor`.
- For the next page, pass `cursor=nextCursor` with the same filters and sort. Offset `page` remains supported when no cursor is supplied.

Create payload shape:

```json
{
  "strategyId": "9a46ddf3-98fd-4cf5-8fd0-022421741c35",
  "from": "2026-05-16T00:00:00.000Z",
  "to": "2026-05-23T00:00:00.000Z",
  "labelDefinition": {
    "threshold": 2
  },
  "options": {
    "eventType": "new_token_created",
    "strictOverride": true
  }
}
```

Field notes:

- `strategyId`: required Strategy UUID owned by the API-key user
- `from` / `to`: required ISO 8601 datetimes
- `labelDefinition.threshold`: required winner multiple threshold
- `options`: required object; send `{}` when no options are needed
- `options.eventType`: optional event type filter
- `options.strictOverride`: optional boolean strict-mode override

## Canonical request and response examples

Use these examples as the default reference shapes.

### `GET /me`

Request:

```bash
curl -X GET 'https://api.memeperfect.io/api/external/v1/me' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response:

```json
{
  "userId": "4fcb13dc-2f0c-49bb-97a3-2f2f7ac0f80f",
  "plan": "PRO",
  "limits": {
    "strategies": {
      "total": null,
      "active": 25
    },
    "rateLimit": {
      "requestsPerMinute": 60
    }
  }
}
```

### `POST /strategies`

Request:

```bash
curl -X POST 'https://api.memeperfect.io/api/external/v1/strategies' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "API Safe Launch Flow",
    "description": "Programmatic strategy for safer early launches",
    "strict": true,
    "alertCooldownMins": 30,
    "triggers": ["new_token_created"],
    "rules": [
      {
        "rule": "is_honeypot",
        "dealbreaker": true,
        "enabled": true
      },
      {
        "rule": "market_cap",
        "dealbreaker": true,
        "min": 2500,
        "max": 180000
      },
      {
        "rule": "risk_level",
        "dealbreaker": false,
        "value": "LOW"
      },
      {
        "rule": "liquidity_usd",
        "dealbreaker": false,
        "min": 3000
      },
      {
        "rule": "has_twitter",
        "dealbreaker": false,
        "enabled": true
      }
    ],
    "matching": {
      "enabled": true,
      "minPercent": 80
    },
    "isActive": false
  }'
```

Followed developer trigger config examples:

```json
{
  "triggers": ["followed_dev_new_token_created"],
  "triggerConfigs": {
    "followed_dev_new_token_created": {
      "scope": "all"
    }
  }
}
```

```json
{
  "triggers": ["followed_dev_new_token_created"],
  "triggerConfigs": {
    "followed_dev_new_token_created": {
      "scope": "tag",
      "tagId": "b0d6a1d8-6e6c-4f80-9a61-5b8a3c4b2a11"
    }
  }
}
```

```json
{
  "triggers": ["followed_dev_new_token_created"],
  "triggerConfigs": {
    "followed_dev_new_token_created": {
      "scope": "wallet",
      "developerAddress": "7xKXExampleDeveloperWallet"
    }
  }
}
```

Response:

```json
{
  "strategy": {
    "id": "9a46ddf3-98fd-4cf5-8fd0-022421741c35",
    "name": "API Safe Launch Flow",
    "description": "Programmatic strategy for safer early launches",
    "userId": "4fcb13dc-2f0c-49bb-97a3-2f2f7ac0f80f",
    "strict": true,
    "alertCooldownMins": 30,
    "isActive": false,
    "isGlobal": false,
    "matching": {
      "enabled": true,
      "minPercent": 80
    },
    "createdAt": "2026-03-09T08:25:58.221Z",
    "updatedAt": "2026-03-09T08:25:58.221Z"
  }
}
```

### `PATCH /strategies/:id`

Request:

```bash
curl -X PATCH 'https://api.memeperfect.io/api/external/v1/strategies/9a46ddf3-98fd-4cf5-8fd0-022421741c35' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "alertCooldownMins": 45,
    "rules": [
      {
        "rule": "is_honeypot",
        "dealbreaker": true,
        "enabled": true
      },
      {
        "rule": "market_cap",
        "dealbreaker": true,
        "min": 2500,
        "max": 180000
      },
      {
        "rule": "liquidity_usd",
        "dealbreaker": false,
        "min": 5000
      },
      {
        "rule": "tx_count",
        "dealbreaker": false,
        "min": 100
      }
    ]
  }'
```

Response:

```json
{
  "strategy": {
    "id": "9a46ddf3-98fd-4cf5-8fd0-022421741c35",
    "alertCooldownMins": 45,
    "updatedAt": "2026-03-09T09:10:18.401Z"
  }
}
```

### `GET /notifications`

Request:

```bash
curl -X GET 'https://api.memeperfect.io/api/external/v1/notifications?page=1&limit=20&strategyId=9a46ddf3-98fd-4cf5-8fd0-022421741c35' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response:

```json
{
  "items": [
    {
      "id": "497e3b40-3a6e-449f-87cd-4f96af15cffe",
      "userId": "4fcb13dc-2f0c-49bb-97a3-2f2f7ac0f80f",
      "strategyId": "9a46ddf3-98fd-4cf5-8fd0-022421741c35",
      "channel": "telegram",
      "status": "sent",
      "triggerEventType": "new_token_created",
      "triggerContext": {
        "tokenAddress": "7xKXExampleAddress",
        "tokenData": {
          "tokenSymbol": "EXAMPLE",
          "market": {
            "priceUSD": 0.00012,
            "mcap": 120000
          }
        }
      },
      "sentAt": "2026-03-09T08:31:05.120Z",
      "createdAt": "2026-03-09T08:31:05.120Z",
      "updatedAt": "2026-03-09T08:31:05.120Z",
      "strategy": {
        "id": "9a46ddf3-98fd-4cf5-8fd0-022421741c35",
        "name": "API Safe Launch Flow"
      }
    }
  ],
  "page": 1,
  "limit": 20,
  "total": 1,
  "totalPages": 1
}
```

### `GET /notifications/performance`

Request:

```bash
curl -X GET 'https://api.memeperfect.io/api/external/v1/notifications/performance?range=daily&strategyId=9a46ddf3-98fd-4cf5-8fd0-022421741c35' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response:

```json
{
  "range": "daily",
  "summary": {
    "notifications": 12,
    "wins": 4,
    "losses": 3,
    "pending": 5,
    "winRate": 57.14
  }
}
```

### `GET /notifications/performance/last`

Read the last cached performance summary without starting a fresh calculation.

Request:

```bash
curl -X GET 'https://api.memeperfect.io/api/external/v1/notifications/performance/last?range=daily&strategyId=9a46ddf3-98fd-4cf5-8fd0-022421741c35' \
  -H 'X-API-Key: YOUR_API_KEY'
```

### `GET /strategy-evaluations`

Use this endpoint to inspect persisted Strategy evaluations, including matched and non-matched evaluations.

Request:

```bash
curl -X GET 'https://api.memeperfect.io/api/external/v1/strategy-evaluations?pageSize=50&strategyId=9a46ddf3-98fd-4cf5-8fd0-022421741c35&from=2026-03-09T00:00:00.000Z&to=2026-03-10T00:00:00.000Z' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Supported query parameters:

- `page`: page number, 1-based; used when `cursor` is not provided
- `pageSize`: page size, capped at 100
- `limit`: compatibility alias for `pageSize`; `pageSize` wins when both are sent
- `cursor`: opaque cursor returned as `nextCursor`; use with the same filters and sort
- `sortBy`: `createdAt`, `matched`, `evaluationTimeMs`, `tokenAddress`, `strategyId`, `mcap`, `liquidity`
- `sortDir`: `asc` or `desc`
- `matched`: `true` or `false`
- `strategyId`: Strategy UUID
- `address`: token address exact match, or partial match when `%` is present
- `datetime`: ISO datetime minute window, or `YYYY-MM-DD` day window
- `dealbreakerFailed`: `true` or `false`
- `failedGroupIds`: comma-separated group IDs or repeated query params
- `from`: ISO 8601 lower bound for evaluation `createdAt`
- `to`: ISO 8601 upper bound for evaluation `createdAt`

Response:

```json
{
  "items": [
    {
      "evaluationId": "eval-1",
      "strategyId": "9a46ddf3-98fd-4cf5-8fd0-022421741c35",
      "strategyName": "API Safe Launch Flow",
      "userId": "4fcb13dc-2f0c-49bb-97a3-2f2f7ac0f80f",
      "tokenAddress": "7xKXExampleAddress",
      "eventType": "new_token_created",
      "matched": false,
      "matchDetails": {},
      "failureReason": "dealbreaker_failed",
      "failedRules": ["db-honeypot"],
      "baselineAt": "2026-03-09T08:31:05.120Z",
      "baselinePrice": 0.00012,
      "baselineMcap": 120000,
      "currentMcap": 140000,
      "sourceContext": {},
      "debugTrail": []
    }
  ],
  "page": 1,
  "pageSize": 50,
  "total": null,
  "hasMore": true,
  "nextCursor": "eyJ2IjoxLCJzb3J0QnkiOiJjcmVhdGVkQXQiLCJzb3J0RGlyIjoiREVTQyIsImlkIjoiZXZhbC0xIn0"
}
```

For the next page, send `cursor=nextCursor` with the same filters and sort.

### `POST /backtests`

Request:

```bash
curl -X POST 'https://api.memeperfect.io/api/external/v1/backtests' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "strategyId": "9a46ddf3-98fd-4cf5-8fd0-022421741c35",
    "from": "2026-05-16T00:00:00.000Z",
    "to": "2026-05-23T00:00:00.000Z",
    "labelDefinition": {
      "threshold": 2
    },
    "options": {
      "eventType": "new_token_created",
      "strictOverride": true
    }
  }'
```

Response:

```json
{
  "id": "39bcdd52-7e7e-4854-a3d7-b49c59b6fd21",
  "status": "QUEUED",
  "strategyId": "9a46ddf3-98fd-4cf5-8fd0-022421741c35"
}
```

### `GET /backtests/:id/results`

Request:

```bash
curl -X GET 'https://api.memeperfect.io/api/external/v1/backtests/39bcdd52-7e7e-4854-a3d7-b49c59b6fd21/results?page=1&pageSize=50&matched=true&sortBy=multiple&sortDir=desc' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response:

```json
{
  "items": [
    {
      "tokenAddress": "7xKXExampleAddress",
      "matched": true,
      "multiples": {
        "0": 2.4
      },
      "snapshot": {
        "strategyId": "9a46ddf3-98fd-4cf5-8fd0-022421741c35",
        "strategyName": "API Safe Launch Flow",
        "matched": true
      }
    }
  ],
  "page": 1,
  "pageSize": 50,
  "total": 1,
  "hasMore": false,
  "todayCount": 3
}
```

### Twitter endpoints

Use these read-only endpoints for Twitter Handles and tags configured in MemePerfect.

Supported endpoints:

- `GET /twitter/handles`
- `GET /twitter/tags`

`GET /twitter/handles` query parameters:

- `search`: search in handle and tags
- `tagId`: filter by tag id
- `status`: `active` or `inactive`

`GET /twitter/tags` query parameters:

- `includeCounts`: boolean
- `sortBy`: `name`, `createdAt`, or `handleCount`
- `sortOrder`: `asc` or `desc`
- `scope`: `all`, `user`, or `platform`

### Developer tracking endpoints

Use these endpoints to read and manage followed developer wallets and developer tags.

Supported endpoints:

- `GET /devs/my`
- `GET /devs/tags`
- `GET /devs/:address/tags`
- `POST /devs/:address/add`
- `PUT /devs/:address/update`
- `PUT /devs/:address/tags`
- `PATCH /devs/tags/:id`
- `DELETE /devs/tags/:id`

`GET /devs/my` query parameters:

- `page`: page number, default `1`
- `limit`: page size, default `20`
- `isActive`: boolean filter
- `tagId`: developer tag id filter

Developer request body shapes:

```json
{
  "alias": "Solana King"
}
```

```json
{
  "alias": "Updated Solana King",
  "isActive": true
}
```

```json
{
  "tagIds": ["b0d6a1d8-6e6c-4f80-9a61-5b8a3c4b2a11"]
}
```

```json
{
  "name": "Conviction Devs",
  "color": "#22c55e",
  "notes": "High quality launch history"
}
```

### `PUT /webhook`

Request:

```bash
curl -X PUT 'https://api.memeperfect.io/api/external/v1/webhook' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "enabled": true,
    "url": "https://your-domain.com/memeperfect/webhook"
  }'
```

Response:

```json
{
  "enabled": true,
  "url": "https://your-domain.com/memeperfect/webhook",
  "verifiedAt": "2026-03-09T08:36:21.522Z",
  "hasSecret": true,
  "secret": "whsec_9SNQ...",
  "verificationError": null
}
```

## Rule group contract

For create and update requests, agents must not send arbitrary `ruleGroups`.
Always send the documented flat external `rules[]` payload.

The backend maps non-dealbreaker rules into product groups such as:

- `security` with name `Security`
- `market` with name `Market`
- `volume_activity` or equivalent returned group with name `Volume/Activity`
- `clusters` or equivalent returned group with name `Clusters`
- `socials` with name `Socials`
- `ai` with name `AI`

Read endpoints may return internal `dealbreakers` and `ruleGroups`. Treat those as response artifacts unless the docs explicitly allow sending them back.

Do not invent group IDs, group names, internal rule IDs, or internal operators.

## Allowed trigger eventType values

Use only these documented `eventType` values:

- `new_token_created`
- `followed_dev_new_token_created`
- `twitter_mention_direct`
- `tweet_metadata_match`
- `token_almost_graduated`
- `token_graduated`

## Rule object contract

Create and update requests use a flat external `rules` array. Each rule uses one of these shapes:

Boolean rule:

```json
{
  "rule": "is_honeypot",
  "dealbreaker": true,
  "enabled": true
}
```

Numeric rule:

```json
{
  "rule": "market_cap",
  "dealbreaker": true,
  "min": 2500,
  "max": 180000
}
```

Enum rule:

```json
{
  "rule": "risk_level",
  "dealbreaker": false,
  "value": "LOW",
  "operator": "equals"
}
```

Object rule:

```json
{
  "rule": "validated_volume_spike",
  "dealbreaker": false,
  "config": {
    "window": "5m",
    "volumeSpike": "very_strong"
  }
}
```

Cluster rule:

```json
{
  "rule": "coordinated_wallet_cluster",
  "dealbreaker": false,
  "clusterConfig": {
    "maxTotalHeldPct": 20,
    "maxSingleClusterPct": 10,
    "maxClusterRisk": "high"
  }
}
```

External rule fields:

- `rule`: required exact rule id from the catalog below
- `dealbreaker`: required boolean; `true` maps the rule to a hard Dealbreaker, `false` maps it into the canonical category group
- `enabled`: boolean rules only; `true` applies the rule's documented default, `false` skips it
- `min`: numeric rules only; maps to internal `greater_than`
- `max`: numeric rules only; maps to internal `less_than`
- `value`: enum rules only, such as `risk_level` or `launch_platform`
- `operator`: enum rules only; `equals` or `not_equals`, defaulting to `equals`
- `config`: object rules only; used by advanced market, volume/activity, and wallet-quality checks
- `clusterConfig`: coordinated wallet cluster rules only

Do not send internal fields such as `id`, `ruleType`, `value` for numeric rules, `dealbreakers`, or `ruleGroups` in create/update requests. Read endpoints may return those internal fields after the backend maps the flat external rules.

Object rule constraints:

- `volume_24h` accepts age-aware `config.windows` such as `5m`, `1h`, `6h`, and `24h`
- `buy_sell_ratio_window` accepts `config.window` and `config.buyPressure`
- `validated_volume_spike` accepts `config.window` and `config.volumeSpike`
- `quality_wallet_count`, `quality_wallet_total_value`, and `quality_wallet_min_winrate` accept wallet-quality settings through `config`
- wallet-quality rules are API-backed third-party rules and cannot be Dealbreakers

Allowed `buyPressure` values:

- `off`
- `slight`
- `moderate`
- `strong`
- `aggressive`

Allowed `volumeSpike` values:

- `off`
- `noticeable`
- `strong`
- `very_strong`
- `explosive`

Allowed wallet-quality `walletTypes`:

- `smart_wallet`
- `kol`
- `whale`
- `profitable_trader`

Cluster rule constraints:

- `coordinated_wallet_cluster` accepts `clusterConfig.maxTotalHeldPct`, `clusterConfig.maxSingleClusterPct`, and `clusterConfig.maxClusterRisk`
- allowed `maxClusterRisk` values are `low`, `medium`, `high`, and `very_high`
- coordinated wallet cluster rules are API-backed third-party rules and cannot be Dealbreakers

## Rule catalog

Use only documented rule ids in the external `rule` field. The backend assigns non-dealbreaker rules to product groups.

### Security rule ids

- `is_honeypot`
- `is_mintable`
- `top_10_holder_percent`
- `dev_wallet_percent`
- `is_lp_locked`
- `risk_level`
- `rugged`
- `lp_locked_pct`
- `has_freeze_authority`
- `has_high_ownership`
- `has_top10_high_ownership`
- `has_single_holder_ownership`
- `has_creator_rug_history`
- `has_low_lp_providers`
- `has_low_liquidity`
- `creator_has_multiple_tokens`
- `has_creator_balance`
- `has_lockers`
- `risk_count`
- `token_mutable`
- `has_transfer_fee`
- `token_age`

`token_age` is evaluated in minutes. Do not use old hour-based thresholds.

### Market rule ids

- `sell_tax`
- `buy_tax`
- `liquidity_usd`
- `market_cap`
- `kols`
- `global_fees_paid`
- `pro_traders`
- `snipers`
- `insiders`
- `bundle`
- `dev_migrations`
- `dev_pairs_created`
- `bonding_progress`
- `launch_platform`
- `is_pump`
- `holder_count`

### Volume/Activity rule ids

- `volume_24h`
- `tx_count`
- `num_buys`
- `num_sells`
- `buy_sell_ratio_window`
- `validated_volume_spike`
- `quality_wallet_count`
- `quality_wallet_total_value`
- `quality_wallet_min_winrate`

### Clusters rule ids

- `coordinated_wallet_cluster`

### Socials rule ids

- `has_website`
- `has_telegram`
- `has_twitter`
- `at_least_one_social`
- `website_has_ca`
- `website_contains_token_name`
- `twitter_link_has_ca`
- `x_link_contains_token_name`
- `twitter_effective_views`
- `x_community_member_count`
- `x_community_views_count`
- `twitter_effective_followers`

### AI rule ids

- `website_content_validation_score`
- `x_content_validation_score`

## Rule value guidance

Use these operator and value patterns:

- boolean rules use `enabled: true` to apply the rule's documented default, or `enabled: false` to skip the rule
- numeric and percentage rules use `min` and/or `max`
- enum rules such as `risk_level` use `value` and optionally `operator: "equals"` or `operator: "not_equals"`

Known enum values:

- `risk_level`: `CRITICAL`, `HIGH`, `MEDIUM`, `LOW`
- `launch_platform`: `pump_fun`, `letsbonk_fun`, `bags_fm`, `rapidlaunch`, `raydium_launchlab`, `dexlab`, `meteora`

`risk_level` is threshold-like in the core rules engine. `equals: LOW` matches only `LOW`; `equals: HIGH` matches `HIGH`, `MEDIUM`, and `LOW`. `launch_platform` is exact-match for both `equals` and `not_equals`.

AI preset guidance:

- `very_relevant` maps to score range rules `min: 80` and `max: 100`
- `somewhat_relevant` maps to score range rules `min: 50` and `max: 100`
- `any` means omit those AI score rules

## Workflow

Use this order for most integrations:

1. Call `GET /me` to confirm authentication, plan, and limits.
2. Build a valid Strategy payload using the fixed rule groups and allowed trigger values.
3. Call `POST /strategies` to create the Strategy.
4. Call `POST /strategies/:id/activate` to make it live.
5. Optionally call `POST /backtests`, poll `GET /backtests/:id`, and inspect `GET /backtests/:id/results` before relying on the Strategy.
6. Call `GET /notifications` or `GET /notifications/:id` to read outcomes.
7. Call `GET /notifications/performance` or async performance job endpoints for results analysis.
8. Call `PUT /webhook` if the user wants programmatic delivery.
9. Call `PATCH /strategies/:id` or `POST /strategies/:id/deactivate` when changing or disabling behavior.

## Agent workflow modes

Use these modes when deciding how aggressively to act.

### Careful mode

1. Read `GET /me`.
2. Show the proposed Strategy payload to the human before creation.
3. Create with `isActive: false`.
4. Wait for approval before activation.

### Standard mode

1. Read `GET /me`.
2. Create a valid Strategy from the user request.
3. Activate if the user explicitly asked for a live Strategy.
4. Configure webhook only if the user provided an endpoint.

### Maintenance mode

1. Fetch the existing Strategy.
2. Update only the requested fields.
3. Preserve fixed group IDs and names.
4. Re-check notifications or performance after the update if the user asked for validation.

## Webhook behavior

Webhook configuration is available through the external API.

Important constraints:

- setting or changing the webhook URL triggers endpoint verification
- webhook signing uses `X-MP-Signature`
- verification uses a challenge-response flow
- webhook delivery should be treated as best-effort

## Errors

Expect at least these status codes:

- `400` invalid body, query, or path parameters
- `401` missing or invalid API key
- `403` subscription required or active Strategy limit reached
- `404` resource not found or not owned by the authenticated user
- `429` rate limit exceeded

Common error shape:

```json
{
  "statusCode": 401,
  "message": "API key required. Provide via X-API-Key header or Authorization: ApiKey <key>",
  "error": "Unauthorized"
}
```

## Do not assume

Agents must not claim or attempt undocumented public API capabilities.

Do not assume public API support for:

- template cloning
- Watchlist management
- Telegram settings changes
- UI wizard actions
- internal admin endpoints

If a user asks for one of these, explain that it is not documented in the public external API and point them to the main docs for product guidance.

## Common mistakes to avoid

- Do not use arbitrary rule group names or IDs.
- Do not describe UI actions as API actions.
- Do not use undocumented trigger names.
- Do not omit `alertCooldownMins` when documenting full Strategy behavior.
- Do not say all rules always need to pass; account for `Dealbreakers`, per-group `logic`, and `Flexible Matching`.
- Do not expose API keys in browser code.

## Reference docs

Use these docs for deeper context:

- `https://docs.memeperfect.io/llms.txt`
- `https://docs.memeperfect.io/developers/apis`
- `https://docs.memeperfect.io/developers/api-walkthrough`
- `https://docs.memeperfect.io/developers/strategy-rules`
- `https://docs.memeperfect.io/developers/webhooks`
