CastTool Help
API

API reference

All endpoints, parameters and responses of the API, generated from the OpenAPI description.

This page is generated at build time from the same description that GET /v1/openapi.json serves. It therefore cannot drift from the API. How keys, permissions, pages and errors work is described under Getting started.

Base address: https://api.casttool.net

Machine-readable description (OpenAPI 3.1): https://api.casttool.net/v1/openapi.json

Endpoints

GET /v1/me

Tenant and scopes of the API key in use

Key scope: any valid key

Responses

  • 200 Tenant and scopes of the API key in use Me
  • 401 Missing, unknown, revoked or expired API key Error
  • 403 The key lacks the scope, or the tenant is suspended Error
  • 429 Too many requests Error

GET /v1/models

List models, ordered by id

Key scope: models:read

Parameters

FieldInTypeRequiredNotes
limitqueryintegerNumber of items on one page · default 50, minimum 1, maximum 100
cursorquerystring`nextCursor` of the previous page
statusquery"active" | "inactive"Only models with this status

Responses

  • 200 List models, ordered by id ModelPage
  • 400 Invalid input Error
  • 401 Missing, unknown, revoked or expired API key Error
  • 403 The key lacks the scope, or the tenant is suspended Error
  • 429 Too many requests Error

POST /v1/models

Create a model. It starts inactive and is published in the dashboard.

Key scope: models:write

Request body (JSON)

FieldTypeRequiredNotes
firstNamestringyesminLength 1, maxLength 100
lastNamestringyesminLength 1, maxLength 100
emailstring (email)yesmaxLength 254
mobilestring | nullmaxLength 50
landlinestring | nullmaxLength 50
addressstring | nullmaxLength 500
dateOfBirthstring (date) | null
genderstring | nullmaxLength 200
pronounsstring | nullmaxLength 200
categorystring | nullmaxLength 200
bodyTypestring | nullmaxLength 200
eyeColorstring | nullmaxLength 200
hairColorstring | nullmaxLength 200
ethnicIdentitystring | nullmaxLength 200
hasDriverLicenseboolean
specialFeaturesstring | nullmaxLength 5000
currentLocationstring[]maxItems 100
dialectsstring[]maxItems 100
ethnicOriginsstring[]maxItems 100
languagesstring[]maxItems 100
nationalitiesstring[]maxItems 100
previousClientsstring[]maxItems 100
talentsstring[]maxItems 100
measurementsobject
measurements.heightstring | numbermaxLength 40
measurements.weightstring | numbermaxLength 40
measurements.buststring | numbermaxLength 40
measurements.waiststring | numbermaxLength 40
measurements.hipstring | numbermaxLength 40
measurements.shoeSizestring | numbermaxLength 40
measurements.dressSizestring | numbermaxLength 40
measurements.jeansSizestring | numbermaxLength 40
socialMediaobject
socialMedia.instagramstringmaxLength 300
socialMedia.tiktokstringmaxLength 300
socialMedia.youtubestringmaxLength 300
socialMedia.twitchstringmaxLength 300

Responses

  • 201 Create a model. It starts inactive and is published in the dashboard. Without the scope `models:read` the response is `ModelWriteReceipt`. ModelResponse | ModelWriteReceipt
  • 400 Invalid input Error
  • 401 Missing, unknown, revoked or expired API key Error
  • 402 The subscription only allows reading Error
  • 403 The key lacks the scope, or the tenant is suspended Error
  • 409 The address is already registered in this tenant Error
  • 429 Too many requests Error

GET /v1/models/{id}

Read one model

Key scope: models:read

Parameters

FieldInTypeRequiredNotes
idpathstringyesIdentifier of the resource

Responses

  • 200 Read one model ModelResponse
  • 400 Invalid input Error
  • 401 Missing, unknown, revoked or expired API key Error
  • 403 The key lacks the scope, or the tenant is suspended Error
  • 404 Not found in this tenant Error
  • 429 Too many requests Error

PATCH /v1/models/{id}

Change the profile of a model. Status and visibility stay in the dashboard. A date of birth under 18 takes a public profile offline until a parent has given consent.

Key scope: models:write

Parameters

FieldInTypeRequiredNotes
idpathstringyesIdentifier of the resource

Request body (JSON)

FieldTypeRequiredNotes
firstNamestringminLength 1, maxLength 100
lastNamestringminLength 1, maxLength 100
emailstring (email)maxLength 254
mobilestring | nullmaxLength 50
landlinestring | nullmaxLength 50
addressstring | nullmaxLength 500
dateOfBirthstring (date) | null
genderstring | nullmaxLength 200
pronounsstring | nullmaxLength 200
categorystring | nullmaxLength 200
bodyTypestring | nullmaxLength 200
eyeColorstring | nullmaxLength 200
hairColorstring | nullmaxLength 200
ethnicIdentitystring | nullmaxLength 200
hasDriverLicenseboolean
specialFeaturesstring | nullmaxLength 5000
currentLocationstring[]maxItems 100
dialectsstring[]maxItems 100
ethnicOriginsstring[]maxItems 100
languagesstring[]maxItems 100
nationalitiesstring[]maxItems 100
previousClientsstring[]maxItems 100
talentsstring[]maxItems 100
measurementsobject
measurements.heightstring | numbermaxLength 40
measurements.weightstring | numbermaxLength 40
measurements.buststring | numbermaxLength 40
measurements.waiststring | numbermaxLength 40
measurements.hipstring | numbermaxLength 40
measurements.shoeSizestring | numbermaxLength 40
measurements.dressSizestring | numbermaxLength 40
measurements.jeansSizestring | numbermaxLength 40
socialMediaobject
socialMedia.instagramstringmaxLength 300
socialMedia.tiktokstringmaxLength 300
socialMedia.youtubestringmaxLength 300
socialMedia.twitchstringmaxLength 300

Responses

  • 200 Change the profile of a model. Status and visibility stay in the dashboard. A date of birth under 18 takes a public profile offline until a parent has given consent. Without the scope `models:read` the response is `ModelWriteReceipt`. ModelResponse | ModelWriteReceipt
  • 400 Invalid input Error
  • 401 Missing, unknown, revoked or expired API key Error
  • 402 The subscription only allows reading Error
  • 403 The key lacks the scope, or the tenant is suspended Error
  • 404 Not found in this tenant Error
  • 409 The address is already registered in this tenant Error
  • 429 Too many requests Error

GET /v1/inquiries

List inquiries, ordered by id

Key scope: inquiries:read

Parameters

FieldInTypeRequiredNotes
limitqueryintegerNumber of items on one page · default 50, minimum 1, maximum 100
cursorquerystring`nextCursor` of the previous page
statusquery"open" | "accepted" | "rejected" | "booked"Only inquiries with this status

Responses

  • 200 List inquiries, ordered by id InquiryPage
  • 400 Invalid input Error
  • 401 Missing, unknown, revoked or expired API key Error
  • 403 The key lacks the scope, or the tenant is suspended Error
  • 429 Too many requests Error

GET /v1/inquiries/{id}

Read one inquiry

Key scope: inquiries:read

Parameters

FieldInTypeRequiredNotes
idpathstringyesIdentifier of the resource

Responses

  • 200 Read one inquiry InquiryResponse
  • 400 Invalid input Error
  • 401 Missing, unknown, revoked or expired API key Error
  • 403 The key lacks the scope, or the tenant is suspended Error
  • 404 Not found in this tenant Error
  • 429 Too many requests Error

GET /v1/bookings

List confirmed bookings, ordered by id

Key scope: bookings:read

Parameters

FieldInTypeRequiredNotes
limitqueryintegerNumber of items on one page · default 50, minimum 1, maximum 100
cursorquerystring`nextCursor` of the previous page

Responses

  • 200 List confirmed bookings, ordered by id BookingPage
  • 400 Invalid input Error
  • 401 Missing, unknown, revoked or expired API key Error
  • 403 The key lacks the scope, or the tenant is suspended Error
  • 429 Too many requests Error

GET /v1/bookings/{id}

Read one confirmed booking

Key scope: bookings:read

Parameters

FieldInTypeRequiredNotes
idpathstringyesIdentifier of the resource

Responses

  • 200 Read one confirmed booking BookingResponse
  • 400 Invalid input Error
  • 401 Missing, unknown, revoked or expired API key Error
  • 403 The key lacks the scope, or the tenant is suspended Error
  • 404 Not found in this tenant Error
  • 429 Too many requests Error

Responses in detail

Error

FieldTypeRequiredNotes
errorobjectyes
error.codestringyesStable, machine-readable reason
error.messagestringyes
error.issuesobject[]Only for `validation_failed`
error.issues[].pathstringyes
error.issues[].messagestringyes

Me

FieldTypeRequiredNotes
tenantobjectyes
tenant.idstring (uuid)yes
tenant.slugstringyes
tenant.namestringyes
tenant.kind"agency" | "casting"yes
keyobjectyes
key.idstringyes
key.scopes"models:read" | "models:private" | "models:write" | "inquiries:read" | "bookings:read"[]yes

ModelPage

FieldTypeRequiredNotes
dataobject[]yes
data[].idstringyes
data[].firstNamestringyes
data[].lastNamestringyes
data[].status"active" | "inactive"yes
data[].isPublicbooleanyes
data[].featuredbooleanyes
data[].categorystring | nullyes
data[].ageinteger | nullyesOnly for public models
data[].genderstring | nullyes
data[].pronounsstring | nullyes
data[].bodyTypestring | nullyes
data[].eyeColorstring | nullyes
data[].hairColorstring | nullyes
data[].hasDriverLicensebooleanyes
data[].specialFeaturesstring | nullyes
data[].currentLocationstring[]yes
data[].languagesstring[]yes
data[].dialectsstring[]yes
data[].nationalitiesstring[]yes
data[].talentsstring[]yes
data[].previousClientsstring[]yes
data[].measurementsobjectyes
data[].measurements.heightstring
data[].measurements.weightstring
data[].measurements.buststring
data[].measurements.waiststring
data[].measurements.hipstring
data[].measurements.shoeSizestring
data[].measurements.dressSizestring
data[].measurements.jeansSizestring
data[].socialMediaobjectyes
data[].socialMedia.instagramstring
data[].socialMedia.tiktokstring
data[].socialMedia.youtubestring
data[].socialMedia.twitchstring
data[].imagesobjectyesPublished images only. Files waiting for approval have no address here.
data[].images.profileImagestring (uri) | nullyes
data[].images.galleryImagesstring (uri)[]yes
data[].privateobjectOnly with the scope `models:private`
data[].private.emailstring | nullyes
data[].private.mobilestring | nullyes
data[].private.landlinestring | nullyes
data[].private.addressstring | nullyes
data[].private.dateOfBirthstring | nullyes
data[].private.ethnicIdentitystring | nullyes
data[].private.ethnicOriginsstring[]yes
data[].createdAtstring (date-time)yes
data[].updatedAtstring (date-time)yes
nextCursorstring | nullyesPass as `cursor` for the next page, null on the last one

ModelResponse

FieldTypeRequiredNotes
modelobjectyes
model.idstringyes
model.firstNamestringyes
model.lastNamestringyes
model.status"active" | "inactive"yes
model.isPublicbooleanyes
model.featuredbooleanyes
model.categorystring | nullyes
model.ageinteger | nullyesOnly for public models
model.genderstring | nullyes
model.pronounsstring | nullyes
model.bodyTypestring | nullyes
model.eyeColorstring | nullyes
model.hairColorstring | nullyes
model.hasDriverLicensebooleanyes
model.specialFeaturesstring | nullyes
model.currentLocationstring[]yes
model.languagesstring[]yes
model.dialectsstring[]yes
model.nationalitiesstring[]yes
model.talentsstring[]yes
model.previousClientsstring[]yes
model.measurementsobjectyes
model.measurements.heightstring
model.measurements.weightstring
model.measurements.buststring
model.measurements.waiststring
model.measurements.hipstring
model.measurements.shoeSizestring
model.measurements.dressSizestring
model.measurements.jeansSizestring
model.socialMediaobjectyes
model.socialMedia.instagramstring
model.socialMedia.tiktokstring
model.socialMedia.youtubestring
model.socialMedia.twitchstring
model.imagesobjectyesPublished images only. Files waiting for approval have no address here.
model.images.profileImagestring (uri) | nullyes
model.images.galleryImagesstring (uri)[]yes
model.privateobjectOnly with the scope `models:private`
model.private.emailstring | nullyes
model.private.mobilestring | nullyes
model.private.landlinestring | nullyes
model.private.addressstring | nullyes
model.private.dateOfBirthstring | nullyes
model.private.ethnicIdentitystring | nullyes
model.private.ethnicOriginsstring[]yes
model.createdAtstring (date-time)yes
model.updatedAtstring (date-time)yes

ModelWriteReceipt

FieldTypeRequiredNotes
modelobjectyesWithout the scope `models:read` only id and timestamp, the profile stays unreadable
model.idstringyes
model.updatedAtstring (date-time)yes

InquiryPage

FieldTypeRequiredNotes
dataobject[]yes
data[].idstringyes
data[].status"open" | "accepted" | "rejected" | "booked"yes
data[].offerStatus"pending" | "accepted" | "rejected" | nullyes
data[].namestring | nullyes
data[].emailstring | nullyes
data[].phonestring | nullyes
data[].companystring | nullyes
data[].contactPersonstring | nullyes
data[].projectstring | nullyes
data[].categorystring | nullyes
data[].typestring | nullyes
data[].poNumberstring | nullyes
data[].budgetobjectyes
data[].budget.dailyFeestring | nullyes
data[].budget.travelAndFittingstring | nullyes
data[].budget.overtimestring | nullyes
data[].budget.buyoutstring | nullyes
data[].fittingDateobjectyes
data[].fittingDate.datestring | nullyes
data[].fittingDate.locationstring | nullyes
data[].fittingDate.descriptionstring | nullyes
data[].recallDateobjectyes
data[].recallDate.datestring | nullyes
data[].recallDate.locationstring | nullyes
data[].recallDate.descriptionstring | nullyes
data[].shootingDatesobject[]yes
data[].shootingDates[].datestring | nullyes
data[].shootingDates[].locationstring | nullyes
data[].shootingDates[].descriptionstring | nullyes
data[].modelsobject[]yes
data[].models[].idstringyes
data[].models[].namestringyes
data[].models[].responseStatus"pending" | "available" | "tentative" | "booked" | "unavailable"yes
data[].models[].respondedAtstring (date-time) | nullyes
data[].createdAtstring (date-time)yes
data[].updatedAtstring (date-time)yes
nextCursorstring | nullyesPass as `cursor` for the next page, null on the last one

InquiryResponse

FieldTypeRequiredNotes
inquiryobjectyes
inquiry.idstringyes
inquiry.status"open" | "accepted" | "rejected" | "booked"yes
inquiry.offerStatus"pending" | "accepted" | "rejected" | nullyes
inquiry.namestring | nullyes
inquiry.emailstring | nullyes
inquiry.phonestring | nullyes
inquiry.companystring | nullyes
inquiry.contactPersonstring | nullyes
inquiry.projectstring | nullyes
inquiry.categorystring | nullyes
inquiry.typestring | nullyes
inquiry.poNumberstring | nullyes
inquiry.budgetobjectyes
inquiry.budget.dailyFeestring | nullyes
inquiry.budget.travelAndFittingstring | nullyes
inquiry.budget.overtimestring | nullyes
inquiry.budget.buyoutstring | nullyes
inquiry.fittingDateobjectyes
inquiry.fittingDate.datestring | nullyes
inquiry.fittingDate.locationstring | nullyes
inquiry.fittingDate.descriptionstring | nullyes
inquiry.recallDateobjectyes
inquiry.recallDate.datestring | nullyes
inquiry.recallDate.locationstring | nullyes
inquiry.recallDate.descriptionstring | nullyes
inquiry.shootingDatesobject[]yes
inquiry.shootingDates[].datestring | nullyes
inquiry.shootingDates[].locationstring | nullyes
inquiry.shootingDates[].descriptionstring | nullyes
inquiry.modelsobject[]yes
inquiry.models[].idstringyes
inquiry.models[].namestringyes
inquiry.models[].responseStatus"pending" | "available" | "tentative" | "booked" | "unavailable"yes
inquiry.models[].respondedAtstring (date-time) | nullyes
inquiry.createdAtstring (date-time)yes
inquiry.updatedAtstring (date-time)yes

BookingPage

FieldTypeRequiredNotes
dataobject[]yes
data[].idstringyes
data[].inquiryIdstringyes
data[].termsobjectyes
data[].terms.dailyFeestring | nullyes
data[].terms.travelAndFittingstring | nullyes
data[].terms.overtimestring | nullyes
data[].terms.buyoutstring | nullyes
data[].modelsobject[]yes
data[].models[].idstringyes
data[].models[].namestringyes
data[].confirmedAtstring (date-time)yes
nextCursorstring | nullyesPass as `cursor` for the next page, null on the last one

BookingResponse

FieldTypeRequiredNotes
bookingobjectyes
booking.idstringyes
booking.inquiryIdstringyes
booking.termsobjectyes
booking.terms.dailyFeestring | nullyes
booking.terms.travelAndFittingstring | nullyes
booking.terms.overtimestring | nullyes
booking.terms.buyoutstring | nullyes
booking.modelsobject[]yes
booking.models[].idstringyes
booking.models[].namestringyes
booking.confirmedAtstring (date-time)yes