memories.create_from_file uploads a file, or a piece of text, and Synap extracts the text on the server. That text then goes through the same ingestion pipeline as memories.create: it is split if it is long, its memories are extracted, and they are stored under the person you named. The call returns an ingestion_id right away and the work happens in the background.
Upload a file
Use the right identity: relationship_type
create_from_file takes a relationship_type that the other ingestion calls do not, and it defaults to "b2c". Set it to match your instance:
On a B2B instance the default is wrong and fails silently. With
relationship_type="b2c", the server treats the user as the whole identity and replaces your customer_id with the user_id. The upload succeeds, but its memories are filed under a customer named after the user, and fetches for that user under your real customer do not find them. Check which kind your instance is in B2C vs B2B.
create_from_file always files memories at user scope, because user_id is required. For a document a whole customer or your whole organization should share, such as a policy or a product manual, extract the text and call memories.create with customer_id only (B2B) or with no ids at all; see Identifiers and scopes.
Accepted files
Synap reads text only. Pictures and charts inside a PDF, DOCX or PPTX are not read.
Uploads that cannot be read are refused before anything is stored:
Set the document type
Synap does not detect the type from the file. If you leavedocument_type out, the upload is processed as "document", whatever its extension. The type tells the pipeline what kind of text it is reading; for example, when a long text has to be split, a chat is split at turn and session boundaries and other text at paragraph boundaries. create_from_file passes the value through without checking it, and the server processes a value it does not recognize as "document".
memories.create checks the value against the types the published SDKs accept:
When to extract the text yourself
Extract the text in your own code and callmemories.create with a document_type when:
- The format is not accepted, such as CSV, HTML,
.docor saved email files. - The PDF is scanned. Run OCR first and send the text.
- The file is larger than 10 MB.
- You need the document’s date.
create_from_filehas nodocument_created_at, so Synap cannot tell when the document was written, and a statement like “the contract renews next March” cannot be tied to the right year.memories.createtakes the date. - You need
document_idor a scope path. Neither SDK sends a scope path fromcreate_from_file(the TypeScript options declarescope, but releases up to 0.5.11 do not send it). On a scope ladder with a level between customer and user, usememories.createwithscope. - The document is shared by a customer or your whole organization, as described above.
memories.create defaults to ai-chat-conversation. Set document_type whenever the text is not a chat.
Long documents
Text too long for one extraction pass, a few thousand tokens or more, is split into parts before extraction: conversations at session and turn boundaries, other text at paragraph boundaries. Each later part carries a short excerpt of the text before it, so its extraction has some context from the earlier parts. Each part is processed as its own ingestion job, and theingestion_id you get back belongs to the first part. When memories.status reports completed for that id, the first part is done; later parts may still be in progress.
Duplicates
Synap fingerprints the text it extracted, ignoring differences in whitespace, and remembers the fingerprint for seven days for each user and customer. Uploading the same content again for the same person within that window returns the earlier response, with the sameingestion_id and document_id, and nothing is processed again. That response repeats the status from the first upload, usually queued, so call memories.status to see where the work actually is.
memories.create shares the same check, so the same text sent through it for the same person is also treated as a duplicate. The same file uploaded for a different user is processed for that user. After seven days, the same content is processed again.
Track processing
memories.status returns where an ingestion is: queued, processing, completed, failed or partial_success, along with memories_created, memory_ids and error_message. memories.wait_for_completion polls it for you, every 2 seconds for up to 300 seconds by default.
TimeoutError when time runs out, and TypeScript returns the last status it saw.
Common mistakes
- Leaving
relationship_typeat its default on B2B. The upload succeeds and its memories land under the wrong customer. Passrelationship_type="b2b"with yourcustomer_id. - Passing
filewithoutfilename. The upload is namedupload, has no extension, and is refused as an unsupported type. - Expecting the type to come from the extension. Without
document_type, every upload is processed as"document". - Uploading a scanned PDF. There is no text layer, so nothing can be extracted. OCR it and send the text.
- Uploading shared documents with
create_from_file. They are filed under the one user you named. Usememories.createwithoutuser_idfor content a whole customer or your whole organization should see. - Treating
completedas done for a long document. The returned id covers the first part only. - Expecting a re-upload to be processed again. Within seven days, the same content for the same person returns the earlier ingestion.
- Sending non-chat text to
memories.createwithout a type. It is processed as a chat conversation.
Related pages
memories.create_from_fileandmemories.create: full parameter referencesmemories.statusandmemories.wait_for_completion- How ingestion works: what happens to the text after upload
- Import existing history: loading many documents at once
- Conversations and transcripts: sending what people say rather than what they upload