Partners
`/partners`
One page of records, newest first unless you say otherwise, with the total count in meta so you know how far to paginate.
Required scope: partners:read.
bearerAuthAuthorizationBearer <token>Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.
page?integer1-based. meta.totalPages says how many there are.
1 <= value1per_page?integerRows per page. A value above 200 returns 400 - never a silent clamp.
1 <= value <= 20050sort?stringPrefix with - for descending. An undeclared sort returns 400.
"-createdAt""createdAt""-createdAt""clientName""-clientName""tier""-tier"q?stringCase-insensitive "contains", across: clientName, contactName.
filter[kind]?stringExact match on kind.
"agency""freelance""referrer""consultant"filter[status]?stringExact match on status.
filter[tier]?stringExact match on tier.
filter[clientId]?stringExact match on clientId.
filter[contactId]?stringExact match on contactId.
The requested page.
application/json- response
data*array<>meta*curl -X GET 'https://api.usedashly.com/v1/partners'{ "data": [ { "id": "string", "clientId": "string", "clientName": "string", "contactId": "string", "contactName": "string", "kind": "agency", "tier": "string", "notes": "string", "status": "string", "defaultCommissionBps": 0, "defaultBillingMode": "we_invoice", "defaultCompKind": "commission_pct", "defaultCompBase": "deal_total", "defaultSharedFields": null, "createdAt": "2019-08-24T14:15:22Z" } ], "meta": { "page": 0, "perPage": 0, "total": 0, "totalPages": 0 }}Links are given as the target's public id (clientId: "hsbftmp3f5"); the API resolves them server-side. Fields the database requires but the interface decides for you are filled in the same way here.
Required scope: partners:write.
bearerAuthAuthorizationBearer <token>Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.
Idempotency-Key?stringA value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.
8 <= length <= 255application/json- body
clientId?string|nullcontactId?string|nullkind?string"agency""freelance""referrer""consultant"tier?|nullnotes?string|nulldefaultCommissionBps?|nulldefaultBillingMode?string"we_invoice""partner_invoices"defaultCompKind?string"commission_pct""fixed_amount""none"defaultCompBase?string"deal_total""agency_share""custom"defaultSharedFields?array<>createdAt?stringWhen this actually happened, for an import. Past dates only; defaults to now. updatedAt follows it unless the body sets one.
date-timeCreated. The body is the new record, as a read would return it.
application/json- response
data*curl -X POST 'https://api.usedashly.com/v1/partners' \ -H 'Content-Type: application/json' \ -d '{}'{ "data": { "id": "string", "clientId": "string", "clientName": "string", "contactId": "string", "contactName": "string", "kind": "agency", "tier": "string", "notes": "string", "status": "string", "defaultCommissionBps": 0, "defaultBillingMode": "we_invoice", "defaultCompKind": "commission_pct", "defaultCompBase": "deal_total", "defaultSharedFields": null, "createdAt": "2019-08-24T14:15:22Z" }}The full record, custom fields included when the resource carries them. A record from another agency is a 404, not a 403 - its existence is not ours to confirm.
Required scope: partners:read.
bearerAuthAuthorizationBearer <token>Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.
id*stringThe record's public id (hsbftmp3f5), as returned in the id field. An internal UUID returns 404.
Found.
application/json- response
data*curl -X GET 'https://api.usedashly.com/v1/partners/string'{ "data": { "id": "string", "clientId": "string", "clientName": "string", "contactId": "string", "contactName": "string", "kind": "agency", "tier": "string", "notes": "string", "status": "string", "defaultCommissionBps": 0, "defaultBillingMode": "we_invoice", "defaultCompKind": "commission_pct", "defaultCompBase": "deal_total", "defaultSharedFields": null, "createdAt": "2019-08-24T14:15:22Z" }}A partial update: only the fields you send change. One exception - customFields is replaced wholesale, not merged, so sending it with a single key clears the others. Read the record, merge, then write.
Required scope: partners:write.
bearerAuthAuthorizationBearer <token>Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.
id*stringThe record's public id (hsbftmp3f5), as returned in the id field. An internal UUID returns 404.
application/json- body
kind?string"agency""freelance""referrer""consultant"tier?|nullnotes?string|nullstatus?string"active""revoked"defaultCommissionBps?|nulldefaultBillingMode?string"we_invoice""partner_invoices"defaultCompKind?string"commission_pct""fixed_amount""none"defaultCompBase?string"deal_total""agency_share""custom"defaultSharedFields?array<>Updated. The body is the record as it now stands.
application/json- response
data*curl -X PATCH 'https://api.usedashly.com/v1/partners/string' \ -H 'Content-Type: application/json' \ -d '{}'{ "data": { "id": "string", "clientId": "string", "clientName": "string", "contactId": "string", "contactName": "string", "kind": "agency", "tier": "string", "notes": "string", "status": "string", "defaultCommissionBps": 0, "defaultBillingMode": "we_invoice", "defaultCompKind": "commission_pct", "defaultCompBase": "deal_total", "defaultSharedFields": null, "createdAt": "2019-08-24T14:15:22Z" }}Every verb this resource answers to, with its target and the JSON Schema of its body - the same contracts this document describes, readable at runtime.
Required scope: partners:read.
bearerAuthAuthorizationBearer <token>Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.
The available verbs.
application/json- response
data*array<>curl -X GET 'https://api.usedashly.com/v1/partners/actions'{ "data": [ { "name": "string", "label": "string", "description": "string", "target": "item", "readOnly": true, "path": "string", "input": {} } ]}Deletes the partner row and its people's access; its organisation and contacts stay in the CRM. Refused (409 partner_has_deals) for a partner on any deal, whose history must stay, and (409 partner_has_active_shares) while projects are still shared with it unless closeShares is true.
Does what the dashboard's removePartnerAction does - same implementation, so the two cannot diverge.
Required scope: partners:write.
bearerAuthAuthorizationBearer <token>Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.
id*stringThe public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.
Idempotency-Key?stringA value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.
8 <= length <= 255application/json- body
closeShares?booleanfalseDone.
application/json- response
data*unknownThe action's result; its shape depends on the verb.
curl -X POST 'https://api.usedashly.com/v1/partners/string/actions/remove' \ -H 'Content-Type: application/json' \ -d '{}'{ "data": null}Closes every project shared with this partner and revokes every person at it (their links die too); a partner running a linked Dashly agency also loses the partnership. The partner itself is kept, with its deal history. Returns how many shares and seats were closed.
Does what the dashboard's revokeAllPartnerAccessAction does - same implementation, so the two cannot diverge.
Required scope: partners:write.
bearerAuthAuthorizationBearer <token>Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.
id*stringThe public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.
Idempotency-Key?stringA value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.
8 <= length <= 255application/json- body
Done.
application/json- response
data*unknownThe action's result; its shape depends on the verb.
curl -X POST 'https://api.usedashly.com/v1/partners/string/actions/revoke-all-access' \ -H 'Content-Type: application/json' \ -d '{}'{ "data": null}Sends an invitation to this address to join the partner workspace. Re-inviting the same person renews the link instead of failing.
Does what the dashboard's invitePartnerMemberAction does - same implementation, so the two cannot diverge.
Required scope: partners:write.
bearerAuthAuthorizationBearer <token>Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.
id*stringThe public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.
Idempotency-Key?stringA value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.
8 <= length <= 255application/json- body
email*string^(?:[A-Za-z0-9_'+\-]+\.)*[A-Za-z0-9_'+\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$emaillength <= 200name?stringlength <= 120Done.
application/json- response
data*unknownThe action's result; its shape depends on the verb.
curl -X POST 'https://api.usedashly.com/v1/partners/string/actions/invite-member' \ -H 'Content-Type: application/json' \ -d '{ "email": "user@example.com"}'{ "data": null}Removes this person's access to the partner workspace and cancels their invitation link. The partnership itself is kept.
Does what the dashboard's revokePartnerMemberAction does - same implementation, so the two cannot diverge.
Required scope: partners:write.
bearerAuthAuthorizationBearer <token>Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.
id*stringThe public id of the record to act on. It is resolved inside your agency before the action runs, so an id from another tenant is a 404 and never reaches it.
Idempotency-Key?stringA value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.
8 <= length <= 255application/json- body
email*string^(?:[A-Za-z0-9_'+\-]+\.)*[A-Za-z0-9_'+\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$emaillength <= 200Done.
application/json- response
data*unknownThe action's result; its shape depends on the verb.
curl -X POST 'https://api.usedashly.com/v1/partners/string/actions/revoke-member' \ -H 'Content-Type: application/json' \ -d '{ "email": "user@example.com"}'{ "data": null}Sends this address an invitation to link their agency to yours. The acceptance link goes out by e-mail and is never returned in the response.
Does what the dashboard's invitePartnerAction does - same implementation, so the two cannot diverge.
Required scope: partners:write.
bearerAuthAuthorizationBearer <token>Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.
Idempotency-Key?stringA value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.
8 <= length <= 255application/json- body
email*string^(?:[A-Za-z0-9_'+\-]+\.)*[A-Za-z0-9_'+\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$emaillength <= 200Done.
application/json- response
data*unknownThe action's result; its shape depends on the verb.
curl -X POST 'https://api.usedashly.com/v1/partners/actions/invite-agency' \ -H 'Content-Type: application/json' \ -d '{ "email": "user@example.com"}'{ "data": null}Cancels the pending invitation sent to this address. The invitation is addressed by e-mail, having no public id of its own. Only a pending invitation can be revoked: an accepted one is a partnership, ended with end-agency-partnership.
Does what the dashboard's revokePartnerInvitationAction does - same implementation, so the two cannot diverge.
Required scope: partners:write.
bearerAuthAuthorizationBearer <token>Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.
Idempotency-Key?stringA value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.
8 <= length <= 255application/json- body
email*string^(?:[A-Za-z0-9_'+\-]+\.)*[A-Za-z0-9_'+\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$emaillength <= 200Done.
application/json- response
data*unknownThe action's result; its shape depends on the verb.
curl -X POST 'https://api.usedashly.com/v1/partners/actions/revoke-agency-invitation' \ -H 'Content-Type: application/json' \ -d '{ "email": "user@example.com"}'{ "data": null}Ends the accepted partnership with this agency (either side may end it) and revokes every project shared between the two agencies. A pending invitation is cancelled with revoke-agency-invitation instead.
Does what the dashboard's endPartnershipAction does - same implementation, so the two cannot diverge.
Required scope: partners:write.
bearerAuthAuthorizationBearer <token>Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.
Idempotency-Key?stringA value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.
8 <= length <= 255application/json- body
partnerAgencyId*string1 <= length <= 120Done.
application/json- response
data*unknownThe action's result; its shape depends on the verb.
curl -X POST 'https://api.usedashly.com/v1/partners/actions/end-agency-partnership' \ -H 'Content-Type: application/json' \ -d '{ "partnerAgencyId": "string"}'{ "data": null}Shares every existing project of this client with this linked partner agency, and reports how many were added and how many already were. Projects created afterwards are not included.
Does what the dashboard's shareAllAccountProjectsAction does - same implementation, so the two cannot diverge.
Required scope: partners:write.
bearerAuthAuthorizationBearer <token>Your agency's API key: Authorization: Bearer ak_…. Created in Connectors → API & webhooks and shown once. A key authenticates an agency, not a person.
Idempotency-Key?stringA value you choose (a UUID is the usual one), 8 to 255 characters of A-Z a-z 0-9 _ . : -. Retrying with the same key returns the first call's answer instead of creating a second record, for seven days. The same key with a different body returns 409.
8 <= length <= 255application/json- body
clientId*string1 <= length <= 60partnerAgencyId*string1 <= length <= 120Done.
application/json- response
data*unknownThe action's result; its shape depends on the verb.
curl -X POST 'https://api.usedashly.com/v1/partners/actions/share-client-projects' \ -H 'Content-Type: application/json' \ -d '{ "clientId": "string", "partnerAgencyId": "string"}'{ "data": null}