Platform setup
Set up the resource structure and packages that customer data will use before adding prompts, competitors, or customer access.
Understand the resource hierarchy
The API key selects one workspace. Packages, projects, and locations created with that key stay inside that workspace.
Workspace
├── Package (project)
│ └── Standard project
└── Locations-only project
├── Location → Package (location)
└── Location → Package (location)external_id from your own system when creating projects and locations. You can use it in supported lookup and path parameters instead of storing only Signal UUIDs.Choose project or location scope
Choose the scope from the data you need to track. This decision also determines where packages, prompts, competitors, and visibility data live.
project_mode and package assignment cannot be changed after creation. Create a new resource if the hierarchy needs to change.Configure packages
Create packages before provisioning resources. A project package can be assigned only to standard projects. A location package can be assigned only to locations.
pricing.frontend_delivery_enabled for hosted Signal access and redirect login links.listings.enabled field.{
"package_type": "project",
"configuration": {
"visibility": {
"cadence": "weekly",
"prompt_limit": 100,
"model_keys": ["chatgpt", "claude"]
},
"diagnosis": {
"enabled": true
},
"pricing": {
"frontend_delivery_enabled": true
}
}
}POST /packages/preview. After validation, create the package with POST /packages. To change a package configuration later, clone it and assign the new package to newly created resources.Provision a project
Use a workspace-scoped key with projects:write. Send a stable external ID so future synchronization does not depend on the project name.
Standard project
Supply package_id and website. Set start: true to begin automatic onboarding immediately after the project is created.
curl --request POST \
--url 'https://api.signal.ceyo.ai/v1/projects' \
--header "Authorization: Bearer ${SIGNAL_API_KEY}" \
--header 'Content-Type: application/json' \
--data '{
"name": "Acme Europe",
"external_id": "customer-acme-eu",
"project_mode": "standard",
"package_id": "92404fd7-f096-49e9-9ab0-5ed73517d9db",
"website": "https://acme.example",
"country_code": "NL",
"language": "en",
"start": true
}'Locations-only project
Omit package_id. The locations created under this project select their own location packages.
curl --request POST \
--url 'https://api.signal.ceyo.ai/v1/projects' \
--header "Authorization: Bearer ${SIGNAL_API_KEY}" \
--header 'Content-Type: application/json' \
--data '{
"name": "Acme Locations",
"external_id": "customer-acme-locations",
"project_mode": "locations_only",
"start": false
}'start: false, automatic onboarding is skipped. The resource remains available for manual configuration through the supported settings, prompt, and competitor APIs.Provision a location portfolio
Create the locations-only project first, then create each location beneath its returned project ID or external ID.
location package from the same workspace.external_id, such as a store or account identifier.google_place_id when you have one. Otherwise, send your own local data; city and country_code are enough to use start: true.start independently for each location and poll the returned onboarding_operation.status_url.curl --request POST \
--url 'https://api.signal.ceyo.ai/v1/projects/{project_id}/locations' \
--header "Authorization: Bearer ${SIGNAL_API_KEY}" \
--header 'Content-Type: application/json' \
--data '{
"name": "Acme Amsterdam",
"external_id": "store-nl-ams-01",
"package_id": "66aeb6f8-a353-4acf-a914-e288ca0e4341",
"website": "https://acme.example/amsterdam",
"city": "Amsterdam",
"country_code": "NL",
"language": "nl",
"start": true
}'Without a place ID, onboarding looks for a clear Google match. It keeps your supplied fields, and continues without listing analysis if no match is found. Repeat the request for each location, then use GET /projects/{project_id}/locations or the locations overview endpoint to reconcile the completed portfolio.