
/v4/opportunities/{id}/storing-ids
Get the storingId(s) backing an opportunity, grouped by root campaign. Returns one tree per root campaign matching the requested statuses (default LIVE; past root campaigns are excluded). Each node lists its own storingIds, with sub-campaigns nested under subCampaigns. Sub-campaigns of a matching root are not status-filtered. The same storingId may appear in more than one tree. Stateless campaigns return an empty storingIds array.
Path parameters
idstringOpportunity ID (path-only). Two accepted forms: (1) internal numeric hash, ≤20 digits (e.g. 7673870997270712040), or (2) composite {chainId}-{type}-{identifier} (e.g. 1-ERC20LOGPROCESSOR-0x35Cbe8542E70fa2f7F9cDF129F19e593F4b4f560). The composite form is path-only — query filters (?id=, ?opportunityId=) only accept the numeric form. NOT a campaign ID. See ID types.
Query parameters
campaignStatusstringdefault: LIVEComma-separated statuses to include at the root campaign level (LIVE, PAST, SOON). Default LIVE excludes ended root campaigns. Sub-campaigns under a kept root are not status-filtered.
Responses
200Response for status 200
object[]
campaignIdstringOnchain campaign idstoringIdsstring[]Indexing storingId(s) owned by this campaign only (not children's).subCampaignsany[]Direct sub-campaign nodes; [] for leaves. Always present.[
{
"campaignId": "string",
"storingIds": [
"string"
],
"subCampaigns": [
null
]
}
]404Response for status 404
object
typestringtitlestringstatusnumberdetailstring{
"type": "/errors/not-found",
"title": "Not Found",
"status": 404,
"detail": "Not Found"
}500Response for status 500
object
typestringtitlestringstatusnumberdetailstring{
"type": "string",
"title": "string",
"status": 0,
"detail": "string"
}https://api.merkl.xyz/v4/opportunities//storing-ids?campaignStatus=curl -X GET "https://api.merkl.xyz/v4/opportunities/11521673201667687989/storing-ids?campaignStatus=LIVE"