ConvertKit - v1.0.0
Feed Admin
CRUD endpoints for KitFeed records. The package ships the endpoints — the UI is up to your app.
Base prefix: admin/convertkit (configurable via CONVERTKIT_FEED_ADMIN_PREFIX).
Every endpoint calls the manage-convertkit-feeds Gate. A 403 with no body fires if it fails.
GET /admin/convertkit/feeds
List every feed, ordered by id ASC.
Query params:
| Param | Purpose |
|---|---|
form_id |
Filter to feeds belonging to a specific form. |
Response:
{
"data": [
{
"id": 1,
"form_id": 5,
"name": "Newsletter",
"kit_form_id": 12345,
"kit_tag_ids": [100, 200],
"field_map": { "email_address": "email", "first_name": "name" },
"conditional_logic": null,
"is_active": true,
"created_at": "2026-07-13T14:22:00+00:00",
"updated_at": "2026-07-13T14:22:00+00:00"
}
]
}
Route name: convertkit.feeds.index.
POST /admin/convertkit/feeds
Create a feed.
Request body:
{
"form_id": 5,
"name": "Newsletter",
"kit_form_id": 12345,
"kit_tag_ids": [100, 200],
"field_map": {
"email_address": "email",
"first_name": "name"
},
"conditional_logic": {
"match": "all",
"conditions": [
{ "field": "plan", "operator": "equals", "value": "pro" }
]
},
"is_active": true
}
Validation rules (KitFeedStoreRequest):
| Field | Rules |
|---|---|
form_id |
required, integer, min:1 |
name |
required, string, max:255 |
kit_form_id |
nullable, integer, min:1 |
kit_tag_ids |
array; each item integer, min:1 |
field_map |
required, array, min:1; must contain email_address |
field_map.email_address |
required, string, max:255 |
field_map.* |
string, max:255 |
conditional_logic |
nullable, array |
conditional_logic.match |
nullable, string, in:all,any |
conditional_logic.conditions.*.field |
required with conditions, string |
conditional_logic.conditions.*.operator |
required with conditions, string, in: supported operators |
conditional_logic.conditions.*.value |
nullable |
is_active |
boolean |
Response: 201 Created with the created feed under data.
Route name: convertkit.feeds.store.
GET /admin/convertkit/feeds/{id}
Show a single feed.
Response: 200 OK with the feed under data, or 404 Not Found if the id doesn't exist.
Route name: convertkit.feeds.show.
PUT / PATCH /admin/convertkit/feeds/{id}
Update a feed. All fields optional — the controller merges what was sent.
Validation rules (KitFeedUpdateRequest) are the same as store, but with sometimes in place of required. The field_map still requires an email_address entry when present.
Response: 200 OK with the updated feed under data.
Route name: convertkit.feeds.update.
DELETE /admin/convertkit/feeds/{id}
Delete a feed.
Response: 204 No Content.
Deletion does not touch subscribers already at Kit — see Feeds#deleting-a-feed.
Route name: convertkit.feeds.destroy.
Errors
422 Unprocessable Entity— validation failed.403 Forbidden— Gate denied. The closure receives the resolved feed (ornullforindex/store) so you can key on ownership per record.404 Not Found— feed id doesn't exist (on show/update/delete/test).
Building an admin UI on top
The package doesn't ship one. Common patterns:
- Livewire — a table backed by
GET /admin/convertkit/feedsplus a form forPOST/PUT. Use<x-artisanpack-table>and<x-artisanpack-input>fromartisanpack-ui/livewire-ui-components. - React / Vue — same shape, from the SPA side. The endpoints are stateless JSON so no framework-specific wiring is needed.
- Filament — build a
KitFeedresource on top of the model directly (skipping the REST layer) and rely on the same Gate.