Get DM Config
Read the creator's current DM type, price, and active flag. Owner-only.
GET /api/v1/creators/:creatorId/dm-config — 🔑 Bearer
Returns the calling creator's DM configuration: pricing type (FREE / SINGLE_PAY / PER_MESSAGE), the price (decimal, null when FREE), and the active flag. Ownership-checked — creatorId must match the bearer's CreatorProfile.id.
For a public read of just the DM-related fields (along with dmActive already adjusted for vacation mode), look at the dmType / dmPrice / dmActive fields on GET /bio/:username. This endpoint is the editor-side raw read.
Request
Path parameters
| Param | Type | Validation | Notes |
|---|---|---|---|
creatorId | string (UUID) | ParseUUIDPipe | Must match the bearer's CreatorProfile.id (otherwise 403) |
| Header | Required | Notes |
|---|---|---|
Authorization: Bearer <accessToken> | ✓ | JWT from POST /auth/login |
Response
200 OK — ApiResponseOf<DMConfigResponseDto>
{
"success": true,
"data": {
"dmType": "SINGLE_PAY",
"dmPrice": "5.00",
"dmActive": true
}
}| Field | Type | Notes |
|---|---|---|
dmType | enum | null | FREE / SINGLE_PAY / PER_MESSAGE, or null if never configured |
dmPrice | string | null | Decimal as string for precision; null when dmType === 'FREE' or unconfigured |
dmActive | boolean | Raw value from CreatorProfile.dmActive. The public-render dmActive (in GET /bio/:username) is computed as dmActive && !vacationMode — this endpoint returns the unadjusted raw flag. |
Errors
| HTTP | code / i18nKey | Reason |
|---|---|---|
400 | (validation) | creatorId not a valid UUID |
401 | (guard) | Missing / invalid bearer token |
403 | (verifyCreatorOwnership) | creatorId does not belong to the bearer's user |
404 | creator.dm.not_found | CreatorProfile row missing |
Side effects
- Ownership check —
verifyCreatorOwnership(creatorId, userId)→ 403 on mismatch. prisma.creatorProfile.findUnique({ where: { id: creatorId }, select: { dmType, dmPrice, dmActive } }).- Throw
not_foundif missing. - Return the row. No mutations.
Code samples
curl https://api.bio.re/api/v1/creators/c1a2b3c4-d5e6-7890-abcd-ef1234567890/dm-config \
-H "Authorization: Bearer $ACCESS_TOKEN"type DMConfig = {
dmType: 'FREE' | 'SINGLE_PAY' | 'PER_MESSAGE' | null;
dmPrice: string | null;
dmActive: boolean;
};
async function getDMConfig(accessToken: string, creatorId: string): Promise<DMConfig> {
const res = await fetch(`https://api.bio.re/api/v1/creators/${creatorId}/dm-config`, {
headers: { Authorization: `Bearer ${accessToken}` },
});
const json = await res.json();
if (!res.ok || !json.success) {
throw Object.assign(new Error(json?.error?.message ?? 'DM config fetch failed'), {
code: json?.error?.code,
});
}
return json.data;
}import { useQuery } from '@tanstack/react-query';
export const creatorKeys = {
dmConfig: (creatorId: string) => ['creators', creatorId, 'dm-config'] as const,
};
export function useDMConfig(creatorId: string) {
return useQuery({
queryKey: creatorKeys.dmConfig(creatorId),
queryFn: async () => {
const res = await fetch(`/api/v1/creators/${creatorId}/dm-config`);
const json = await res.json();
if (!res.ok || !json.success) {
throw Object.assign(new Error(json?.error?.message ?? 'DM config fetch failed'), {
code: json?.error?.code,
i18nKey: json?.error?.i18nKey,
});
}
return json.data as DMConfig;
},
enabled: Boolean(creatorId),
staleTime: 30_000,
});
}Try it
Authorization
bearer In: header
Path Parameters
Response Body
application/json
application/json
application/json
curl -X GET "https://loading/api/v1/creators/string/dm-config"{
"success": true,
"data": {
"dmType": "FREE",
"dmPrice": "5.00",
"dmActive": true
}
}{
"success": false,
"error": {
"code": "AUTH_UNAUTHORIZED",
"message": "Invalid credentials",
"i18nKey": "auth.login.invalid_credentials",
"i18nVars": {
"field": "email"
},
"details": [
{
"message": "email must be an email"
}
],
"correlationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
}{
"success": false,
"error": {
"code": "AUTH_UNAUTHORIZED",
"message": "Invalid credentials",
"i18nKey": "auth.login.invalid_credentials",
"i18nVars": {
"field": "email"
},
"details": [
{
"message": "email must be an email"
}
],
"correlationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
}Source
| Source | Path | Lines |
|---|---|---|
| Controller | apps/api-core/src/modules/creator/creator.controller.ts | 203–211 (getDMConfig) |
| DTO (response) | apps/api-core/src/modules/creator/dto/creator-client-response.dto.ts | 460–469 (DMConfigResponseDto) |
| Service | apps/api-core/src/modules/creator/creator.service.ts | 565–572 (getDMConfig) |
| Prisma model | packages/prisma/prisma/schema.prisma | CreatorProfile.dmType, CreatorProfile.dmPrice, CreatorProfile.dmActive |
Get Bio Analytics
Owner-only analytics aggregate for a bio page over a configurable time window. Returns total/unique views, top referrers/devices/countries, and per-day view counts.
Update DM Config
Set DM type / price / active flag in one atomic call. Side effects sync DMPackage rows + flip manual social link visibility on DM ON↔OFF transitions. Public bio cache invalidated.