TypeScript API documentation for monica-cli.
The CLI models two authoritative API editions independently:
- stable — Monica v4.1.2 / branch
4.x, with the complete 35-resource API inmonica-api-reference.json; - next — the current Monica
mainSanctum API, with authenticated-user, account-user, and vault routes inmonica-api-next-reference.json.
The legacy api-reference.json remains available for compatibility. Source research is public and read-only.
Verify that either bundled source commit is still the corresponding public branch head:
monica --json api-research source-status --edition stable
monica --json api-research source-status --edition next
monica --json api-research source-status --edition next --fail-on-stale --fail-on-unavailable
monica --json api-research coverage --source next --fail-on-unmappedcurrent means the bundled commit equals the authoritative branch head.
stale means upstream advanced and the snapshots require review. unavailable
means freshness could not be proven, not that the API is stale. The command
only reads public GitHub branch metadata and never calls the configured Monica
instance. The inherited --request-timeout-ms option bounds this public lookup.
The bundled stable and next inventories can be exported as deterministic OpenAPI documents without contacting the configured Monica instance:
monica --json api-research openapi --edition stable
monica --yaml api-research openapi --edition next --oas-version 3.1.2
monica --json api-research validate-contract --edition stable --fail-on-warnings
monica --json api-research diff --from stable --to nextOpenAPI 3.2.0 is the default; --oas-version 3.1.2 supports tooling that has
not adopted 3.2. The stable contract contains 172 operations across 35
resources, while the current-main contract contains all 9 declared operations
across 3 resources. Each operation carries x-monica provenance, edition,
resource, token-ability, response-shape, and CLI mapping metadata. Bearer
authentication and reusable pagination/error components use standard OpenAPI
structures. Every operation declares an authentication failure response, and
the document identifies Monica's AGPL-3.0-only source license.
validate-contract checks source provenance, operation uniqueness, path
parameters, security, response metadata, and CLI mappings. Add
--verify-source to compare the bundled source commit with the public upstream
branch; this public check never calls the configured instance. diff reports
added, removed, changed, unchanged, and breaking operations. Stable and next
are distinct API editions, so comparing stable to next intentionally reports
stable-only routes as removals.
JSON and YAML are the interoperable OpenAPI serializations. TOON remains the CLI default for compact agent consumption, and Markdown/table remain presentation formats; select JSON or YAML when writing an OpenAPI artifact.
The generated operation IDs are executable without manually translating paths back into resource-specific commands:
monica --json api inspect stable_get_contacts_id
monica --json api get stable_get_contacts_id --param id=1 --query with=contactfields
monica api mutate next_post_vaults --edition next \
--body '{"name":"Example"}' --confirmapi inspect is offline and returns source provenance, CLI mapping, parameters,
request body, responses, and required token ability. api get accepts GET
operations only. api mutate accepts non-GET operations only and requires
--confirm; the client-wide readOnlyMode guard remains authoritative and
blocks the request before dispatch. Path and query keys must be declared by the
operation. Required values, primitive types, enum choices, JSON object fields,
body types, lengths, dates, and PATCH non-empty constraints are checked locally.
The two stable upload operations use multipart input:
monica api mutate stable_post_documents --form contact_id=1 \
--file document=./document.pdf --confirm
monica api mutate stable_post_photos --form contact_id=1 \
--file photo=./photo.jpg --confirmMultipart field/file roles are derived from the contract. In read-only mode,
the command rejects the operation before reading the local file or constructing
an upload. Execution output uses the selected operation's OpenAPI response
schema; inspection output uses the registered api-operation-inspect schema.
The current main branch uses auth:sanctum, UUID resource identifiers, a
read token ability for user/vault reads, and a write ability for vault
mutations. Every route currently declared in upstream routes/api.php maps to
one explicit CLI leaf:
monica users current
monica users list [--all]
monica users get <uuid>
monica vaults list [--all]
monica vaults get <uuid>
monica vaults create --name <name> [--description <text>]
monica vaults update <uuid> --name <name> [--description <text>]
monica vaults patch <uuid> [--name <name>] [--description <text>]
monica vaults delete <uuid>vaults update sends PUT; vaults patch sends PATCH. In read-only mode all
four vault write leaves are rejected before any network call. The setup
connection check tries stable /me first and falls back to current /user
only when the stable route returns HTTP 404 or 405. Authentication,
infrastructure, and timeout failures are preserved instead of being hidden by
an edition fallback.
The public TypeScript surface includes stable resource families and profile actions that older generated API documentation can omit:
- Places:
listPlaces,listAllPlaces,getPlace,createPlace,updatePlace,deletePlace - Life events:
listLifeEvents,listAllLifeEvents,getLifeEvent,createLifeEvent,updateLifeEvent,deleteLifeEvent - Public statistics:
getInstanceStatistics - Upcoming reminders:
listUpcomingReminders - Current-user contact:
setMeContact,unsetMeContact - Contact profile:
updateContactIntroduction,updateContactFoodPreferences,updateContactAvatar,updateContactCareer,setContactAvatar,deleteContactAvatar
All write methods honor the client-wide read-only guard before issuing a request.
bun add monica-cliimport{setConfig}from'monica-cli';setConfig({apiUrl: 'https://your-instance.com/api',apiKey: 'your-jwt-token',});Or use environment variables:
MONICA_API_URL=https://your-instance.com/api
MONICA_API_KEY=your-jwt-tokenGet current configuration.
import{getConfig}from'monica-cli';constconfig=getConfig();// { apiUrl: string, apiKey: string, ... }Set configuration programmatically.
import{setConfig}from'monica-cli';setConfig({apiUrl: 'https://example.com/api',apiKey: 'token',});Custom error class for API errors.
import{MonicaApiError}from'monica-cli';try{awaitgetContact(999);}catch(error){if(errorinstanceofMonicaApiError){console.log(error.message);// Error messageconsole.log(error.errorCode);// Monica error codeconsole.log(error.statusCode);// HTTP status code}}import{paginate,getAllPages}from'monica-cli';// Async generator for paginationforawait(constcontactsofpaginate<Contact>('/contacts')){console.log(contacts);}// Fetch all pages at onceconstallContacts=awaitgetAllPages<Contact>('/contacts');import{listContacts,listAllContacts,getContact,createContact,updateContact,deleteContact,searchContacts,updateContactCareer,getContactLogs,getContactFields,}from'monica-cli';// List contacts (paginated)constresult=awaitlistContacts({page: 1,limit: 10,query: 'john'});// List all contactsconstcontacts=awaitlistAllContacts();// Get a contactconstcontact=awaitgetContact(1);console.log(contact.data);// Get with contact fieldsconstcontactWithFields=awaitgetContact(1,'contactfields');// Create a contactconstnewContact=awaitcreateContact({first_name: 'John',last_name: 'Doe',gender_id: 1,is_birthdate_known: false,is_deceased: false,is_deceased_date_known: false,is_partial: false,});// Update a contactconstupdated=awaitupdateContact(1,{first_name: 'Jane',gender_id: 1,is_birthdate_known: false,is_deceased: false,is_deceased_date_known: false,});// Delete a contactawaitdeleteContact(1);// Search contactsconstresults=awaitsearchContacts('john');// Update careerawaitupdateContactCareer(1,{job: 'Developer',company: 'Acme'});// Get audit logsconstlogs=awaitgetContactLogs(1);// Get contact fieldsconstfields=awaitgetContactFields(1);import{listActivities,listAllActivities,getActivity,createActivity,updateActivity,deleteActivity,listContactActivities,}from'monica-cli';// List activitiesconstactivities=awaitlistActivities({page: 1,limit: 10});// Get activityconstactivity=awaitgetActivity(1);// Create activityconstnewActivity=awaitcreateActivity({activity_type_id: 1,summary: 'Lunch meeting',description: 'Discussed project timeline',happened_at: '2024-01-15',contacts: [1,2],});// Update activityawaitupdateActivity(1,{activity_type_id: 1,summary: 'Updated summary',happened_at: '2024-01-15',contacts: [1],});// Delete activityawaitdeleteActivity(1);// List contact's activitiesconstcontactActivities=awaitlistContactActivities(1);import{listNotes,listAllNotes,getNote,createNote,updateNote,deleteNote,listContactNotes,}from'monica-cli';// Create noteconstnote=awaitcreateNote({body: 'Note content',contact_id: 1,is_favorited: 0,});// Update noteawaitupdateNote(1,{body: 'Updated content',contact_id: 1,is_favorited: 1,});import{listTasks,listAllTasks,getTask,createTask,updateTask,deleteTask,listContactTasks,}from'monica-cli';// Create taskconsttask=awaitcreateTask({title: 'Call John',description: 'Discuss quarterly report',completed: 0,contact_id: 1,});// Update taskawaitupdateTask(1,{title: 'Updated title',completed: 1,completed_at: '2024-01-15',contact_id: 1,});import{listReminders,listAllReminders,getReminder,createReminder,updateReminder,deleteReminder,listContactReminders,}from'monica-cli';// Create reminderconstreminder=awaitcreateReminder({title: 'Birthday reminder',description: 'Remember to send a card',next_expected_date: '2024-06-15',frequency_type: 'year',frequency_number: 1,contact_id: 1,});import{listTags,listAllTags,getTag,createTag,updateTag,deleteTag,setContactTags,unsetContactTag,unsetAllContactTags,listContactsByTag,}from'monica-cli';// Create tagconsttag=awaitcreateTag({name: 'family'});// Set tags on contact (creates tags if needed)awaitsetContactTags(1,{tags: ['family','friend']});// Remove specific tagawaitunsetContactTag(1,{tags: [1,2]});// Remove all tagsawaitunsetAllContactTags(1);// List contacts by tagconstcontacts=awaitlistContactsByTag(1);import{listCompanies,listAllCompanies,getCompany,createCompany,updateCompany,deleteCompany,}from'monica-cli';// Create companyconstcompany=awaitcreateCompany({name: 'Acme Corp',website: 'https://acme.com',number_of_employees: 100,});import{listCalls,listAllCalls,getCall,createCall,updateCall,deleteCall,listContactCalls,}from'monica-cli';// Create callconstcall=awaitcreateCall({contact_id: 1,content: 'Discussed project timeline',called_at: '2024-01-15',});// Update callawaitupdateCall(1,{content: 'Updated notes',called_at: '2024-01-15',});import{listPhotos,listAllPhotos,getPhoto,deletePhoto,listContactPhotos,}from'monica-cli';// List photosconstphotos=awaitlistPhotos({page: 1,limit: 10});// List contact's photosconstcontactPhotos=awaitlistContactPhotos(1);// Get photoconstphoto=awaitgetPhoto(1);// Delete photoawaitdeletePhoto(1);import{listDocuments,listAllDocuments,getDocument,deleteDocument,listContactDocuments,}from'monica-cli';// List documentsconstdocuments=awaitlistDocuments({page: 1,limit: 10});// List contact's documentsconstcontactDocs=awaitlistContactDocuments(1);// Get documentconstdoc=awaitgetDocument(1);// Delete documentawaitdeleteDocument(1);import{listGifts,listAllGifts,getGift,createGift,updateGift,deleteGift,listContactGifts,associateGiftPhoto,}from'monica-cli';// Create giftconstgift=awaitcreateGift({name: 'Birthday present',comment: 'A nice book',status: 'idea',contact_id: 1,});import{listDebts,listAllDebts,getDebt,createDebt,updateDebt,deleteDebt,}from'monica-cli';// Create debtconstdebt=awaitcreateDebt({contact_id: 1,in_debt: 'yes',// 'yes' = user owes contactstatus: 'inprogress',amount: 100,reason: 'Lunch money',});import{listAddresses,listAllAddresses,getAddress,createAddress,updateAddress,deleteAddress,listContactAddresses,}from'monica-cli';// Create addressconstaddress=awaitcreateAddress({contact_id: 1,name: 'Home',street: '123 Main St',city: 'New York',province: 'NY',postal_code: '10001',country_id: 'US',});import{listJournalEntries,listAllJournalEntries,getJournalEntry,createJournalEntry,updateJournalEntry,deleteJournalEntry,}from'monica-cli';// Create entryconstentry=awaitcreateJournalEntry({title: 'Today\'s thoughts',post: 'Long content here...',});import{listGroups,listAllGroups,getGroup,createGroup,updateGroup,deleteGroup,}from'monica-cli';// Create groupconstgroup=awaitcreateGroup({name: 'Close friends'});import{listOccupations,listAllOccupations,getOccupation,createOccupation,updateOccupation,deleteOccupation,listContactOccupations,}from'monica-cli';// Create occupationconstoccupation=awaitcreateOccupation({contact_id: 1,company_id: 1,title: 'Software Engineer',description: 'Full-stack development',salary: 100000,salary_unit: 'year',currently_works_here: true,start_date: '2020-01-15',});import{listConversations,listAllConversations,getConversation,createConversation,updateConversation,deleteConversation,listContactConversations,}from'monica-cli';// Create conversationconstconversation=awaitcreateConversation({contact_id: 1,contact_field_type_id: 1,happened_at: '2024-01-15',});import{getRelationship,createRelationship,deleteRelationship,listRelationships,listRelationshipTypes,getRelationshipType,listRelationshipTypeGroups,getRelationshipTypeGroup,}from'monica-cli';// Create relationshipconstrelationship=awaitcreateRelationship({contact_is: 1,// Primary contactof_contact: 2,// Related contactrelationship_type_id: 1,});// List relationships for contactconstrelationships=awaitlistRelationships(1);// Get a specific relationship type groupconstgroup=awaitgetRelationshipTypeGroup(1);import{listPets,listAllPets,listContactPets,getPet,createPet,updatePet,deletePet,}from'monica-cli';// List pets (paginated)constresult=awaitlistPets({page: 1,limit: 10});// List all petsconstallPets=awaitlistAllPets();// List pets for a specific contactconstcontactPets=awaitlistContactPets(1);// Get a specific petconstpet=awaitgetPet(1);console.log(pet.data);// Create a petconstnewPet=awaitcreatePet({contact_id: 1,name: 'Fluffy',pet_category_id: 1,});// Update a petawaitupdatePet(1,{name: 'Updated name',pet_category_id: 2,});// Delete a petawaitdeletePet(1);import{getUser,listGenders,getGender,createGender,updateGender,deleteGender,listCountries,listCurrencies,getCurrency,listActivityTypes,getActivityType,createActivityType,updateActivityType,deleteActivityType,listActivityTypeCategories,getActivityTypeCategory,createActivityTypeCategory,updateActivityTypeCategory,deleteActivityTypeCategory,listContactFieldTypes,getContactFieldType,createContactFieldType,updateContactFieldType,deleteContactFieldType,listContactFields,getContactField,createContactField,updateContactField,deleteContactField,listCompliance,getCompliance,getUserComplianceStatus,getUserComplianceStatusForTerm,signCompliance,listAuditLogs,}from'monica-cli';// Get current userconstuser=awaitgetUser();// List gendersconstgenders=awaitlistGenders();// List countriesconstcountries=awaitlistCountries();// List currenciesconstcurrencies=awaitlistCurrencies();// List activity typesconstactivityTypes=awaitlistActivityTypes();// List audit logsconstauditLogs=awaitlistAuditLogs({page: 1,limit: 50});All types are exported from the main module:
importtype{Contact,ContactCreateInput,ContactUpdateInput,Activity,ActivityCreateInput,Note,NoteCreateInput,Task,TaskCreateInput,Reminder,ReminderCreateInput,Tag,TagCreateInput,Company,CompanyCreateInput,Call,CallCreateInput,Photo,Document,Gift,GiftCreateInput,Debt,DebtCreateInput,Address,AddressCreateInput,JournalEntry,JournalCreateInput,Group,GroupCreateInput,Occupation,OccupationCreateInput,Conversation,ConversationCreateInput,Relationship,RelationshipCreateInput,Pet,PetCreateInput,PetUpdateInput,PetCategory,Gender,Country,Currency,ActivityType,ActivityTypeCategory,ContactFieldType,ContactField,AuditLog,User,PaginatedResponse,ApiResponse,DeleteResponse,OutputFormat,}from'monica-cli';import{formatOutput,formatPaginatedResponse,formatError,formatSuccess,formatDeleted,ContactFields,ActivityFields,NoteFields,TaskFields,ReminderFields,TagFields,CompanyFields,}from'monica-cli';// Format outputconstoutput=formatOutput(data,'toon');// official lossless TOON// Format paginated responseconstformatted=formatPaginatedResponse(response,'toon',['id','name']);// Format errorconsole.error(formatError(newError('Something went wrong')));// Format successconsole.log(formatSuccess('Contact created',123));// Format deletedconsole.log(formatDeleted(123));formatPaginatedResponse(..., 'toon') encodes the complete filtered
{ data, links, meta } envelope with @toon-format/toon. Consumers can
round-trip it with that package's decode function.