JEN is a data exchange hub that allows you to send and receive data from other users. JSON is sent in the body of the request, and the response is also in JSON format. The data is sent to the server using the POST method. The server will respond with a JSON object containing the data you requested. The server will also respond with an error message if there is an issue with the request.

All calls are made to one address with authentication in the header like in this PHP code:

// Encode the array into a JSON string
                                $jsonData = json_encode($data);

                                // Set your username and password
                                $username = 'hubtest';
                                $password = 'hubpass';

                                // Initialize cURL
                                $ch = curl_init();

                                // Set the URL to which the request will be sent
                                $url = 'https://jen.loyalpuppy.com/dofunctions.php'; 
                                // Set cURL options
                                curl_setopt($ch, CURLOPT_URL, $url);
                                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                                curl_setopt($ch, CURLOPT_POST, 1);

                                // Attach JSON data to the request
                                curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);

                                // Set the headers, including Authorization
                                $headers = [
                                    'Content-Type: application/json',
                                    'Authorization: Basic ' . base64_encode("$username:$password") // Basic auth encoded in base64
                                ];

                                curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

                                // Execute the request
                                $response = curl_exec($ch);


https://jen.loyalpuppy.com/dofunctions.php

Commonalities:

1) All Dates Are In YYYY-MM-DD Format

2) All Times Are In 24 Hour HH:MM Format

3) Whenever There Is A Successful Transaction Involving Sending Or Removing Data, The Response Will Start With OK.
(OK, TransID: 2024092915225166f970cb1351f144055868)

4) Function Names Are Case Sensitive And Must Be Sent Exactly As Shown Below.



FUNCTION REFERENCE

Every call is a POST to the same address with a "Function" field. These are the functions available:

FunctionWhat It DoesReceiver Required?
PINGTest your login and connection.No
NEWCASESend a case with one or more new jobs (and their service documents). Creates Event Code 1. DetailsYes
POSTBACKSSend one or more events (Job Completed, Document Scanned, Attempt, Invoice, Other Note, etc.) about jobs you were sent. DetailsYes, on each event
INCOMING_CASE_LEVEL_DOCUMENTSend a document (base64) for a case you already sent. Creates Event Code 15. DetailsYes
DEFID RESPONSEAnswer a DEFID REQUEST. Creates Event Code 14. See Event Code 14 below.Yes
GETEVENTSPick up events waiting for you (up to 100 per call). DetailsNo
REMOVETRANSMark events you have picked up as done so they are not sent again. DetailsNo
GETJENUSERLook up another JEN user's name and address by their JEN code. DetailsNo
LISTJENUSERSList every JEN member in the member directory (any JEN login). DetailsNo
CANCELCASEWithdraw a case you sent, or some of its jobs. Dropped if not yet picked up, otherwise sends Event Code 17. DetailsYes
CREATEJENUSERPartner logins: create a JEN member and get its JEN code, username and password. DetailsNo
RESETJENUSERPartner logins: issue one of your members a new password. DetailsNo
DISABLEJENUSERPartner logins: turn one of your members' login off. DetailsNo
ENABLEJENUSERPartner logins: turn one of your members' login back on. DetailsNo
SETJENUSERLISTEDPartner logins: show or hide one of your members in the member directory. DetailsNo

Which function sends which Event Code:

Event CodeEvent TypeSend It With
1NEW JOBNEWCASE
2JOB COMPLETEDPOSTBACKS with "etype": 2
3DOCUMENT SCANNEDPOSTBACKS with "etype": 3
4ATTEMPTPOSTBACKS with "etype": 4
6INVOICEPOSTBACKS with "etype": 6
7OTHER NOTEPOSTBACKS with "etype": 7
11CASE LEVEL NOTEPOSTBACKS with "etype": 11
12CASE FILING EVENTPOSTBACKS with "etype": 12
14DEFID RESPONSEDEFID RESPONSE
15INCOMING CASE LEVEL DOCUMENTINCOMING_CASE_LEVEL_DOCUMENT
16LAST DEFENDANT COMPLETEDPOSTBACKS with "etype": 16
17CASE WITHDRAWNCANCELCASE (only when the receiver already picked the case up)
TESTING: Use TESTA as the Receiver for test transactions. Do not send test transactions to your own JEN code or to a live receiver.


PING TO TEST AUTHENTICAITON AND CONNECTION

    $data = [
        "Function" => "PING"
    ];

Encode this into a JSON string and send it to the server: {"Function":"PING"}

If you authenticate correctly, you will get a response of:

Authentication Passed, Ping OK!

Otherwise, you will get one of these (HTTP 403), on this and every other function:

Forbidden - Invalid username or password — the username or password is wrong. For your security the response never repeats back what you sent.
Forbidden - Account disabled — your login is correct but your JEN account has been turned off. Contact JEN support to have it turned back on or to get a new password.



EVENT CODES

When you GETEVENTS (Poll JEN For Various Events Waiting For You To Pick Up), You Will Receive JSON Back With An "etype" Field. This Is The Event Code.

ALL DATES ARE YYYY-MM-DD AND ALL TIMES ARE HH:MM OR HH:MM:SS

Event Codes Can Be:

Code Event Type Fields (in jstext)
1 NEW JOB See Below For NEWCASE Post Requirements
2 JOB COMPLETED YourJobID, YourCaseID, Recipient, YourRecipientID, DateCompleted, TimeCompleted, ServiceType, LongServiceType, JENServiceType, PersonLeftWith, PersonLeftWithTitle, Sex, Skin, Hair, Age, Height, Weight, Other, Married, Military, PropertyType, ServiceComments, Address1, Address2, City, State, Zip, DateMailed, Certified, CertifiedReceiptNum, YourAddressID, SubServerName, SubServerLicence, IsServed
Photos[] (optional): PhotoID, Filename, ExifLatitude, ExifLongitude, ExifTime, GPSDate, GPSTime, Address1, Address2, City, State, Zip, Notes, DownloadLink
Photos array included when completion has associated photos from the process server's mobile app. Each photo includes GPS/EXIF metadata and a download link.
View Sample JSON
{
    "YourJobID": "JOB-5678",
    "YourCaseID": "CASE-2024-001",
    "Recipient": "John Doe",
    "YourRecipientID": "R001",
    "DateCompleted": "2024-12-03",
    "TimeCompleted": "14:30",
    "ServiceType": "PS",
    "LongServiceType": "Personal Service",
    "PersonLeftWith": "John Doe",
    "PersonLeftWithTitle": "Defendant",
    "Sex": "Male",
    "Skin": "Light",
    "Hair": "Brown",
    "Age": "45",
    "Height": "5'10",
    "Weight": "180",
    "Other": "",
    "Married": "YES",
    "Military": "NO",
    "PropertyType": "Single Family Home",
    "ServiceComments": "Served at front door",
    "Address1": "123 Main Street",
    "Address2": "Apt 4B",
    "City": "Miami",
    "State": "FL",
    "Zip": "33101",
    "DateMailed": "",
    "Certified": "0",
    "CertifiedReceiptNum": "",
    "YourAddressID": "Addr001",
    "SubServerName": "Mike Smith",
    "SubServerLicence": "PS-12345",
    "IsServed": "1",
    "Photos": [
        {
            "PhotoID": "67890",
            "Filename": "completion_photo1.jpg",
            "ExifLatitude": "25.7617",
            "ExifLongitude": "-80.1918",
            "ExifTime": "14:30:22",
            "GPSDate": "2024-12-03",
            "GPSTime": "14:30:22",
            "Address1": "123 Main Street",
            "Address2": "Apt 4B",
            "City": "Miami",
            "State": "FL",
            "Zip": "33101",
            "Notes": "Proof of service photo",
            "DownloadLink": "https://example.com/viewphotodirect.php?ownerid=27&token=abc123&id=67890"
        }
    ]
}
3 DOCUMENT SCANNED YourCaseID, YourJobID, YourRecipientID, CaseNo, DocType, ScanID, Filename, DownloadLink
4 ATTEMPT YourCaseID, YourJobID, Dt, Tm, Address1, Address2, City, State, Zip, Note
Photos[] (optional): PhotoID, Filename, ExifLatitude, ExifLongitude, ExifTime, GPSDate, GPSTime, Address1, Address2, City, State, Zip, Notes, DownloadLink
Photos array included when attempt has associated photos. Each photo has its own address/notes from the photo metadata.
View Sample JSON
{
    "YourCaseID": "CASE-2024-001",
    "YourJobID": "JOB-5678",
    "Dt": "2024-12-03",
    "Tm": "14:30",
    "Address1": "123 Main Street",
    "Address2": "Apt 4B",
    "City": "Miami",
    "State": "FL",
    "Zip": "33101",
    "Note": "No answer at door. Left door hanger.",
    "Photos": [
        {
            "PhotoID": "12345",
            "Filename": "attempt_photo1.jpg",
            "ExifLatitude": "25.7617",
            "ExifLongitude": "-80.1918",
            "ExifTime": "14:30:22",
            "GPSDate": "2024-12-03",
            "GPSTime": "14:30:22",
            "Address1": "123 Main Street",
            "Address2": "Apt 4B",
            "City": "Miami",
            "State": "FL",
            "Zip": "33101",
            "Notes": "Front door photo",
            "DownloadLink": "https://example.com/viewphotodirect.php?ownerid=27&token=abc123&id=12345"
        }
    ]
}
6 INVOICE InvoiceNum, InvoiceDate, InvoiceTotal
Jobs[]: Recipient, YourRecipientID, YourCaseID, YourJobID
Items[]: ItemName, ClientChargeCode, Amount, TaxAmount, TotalAmount, DateItemAdded
7 OTHER NOTE YourCaseID, YourJobID, YourRecipientID, Recipient, Dt, Tm, Note
11 CASE LEVEL NOTE YourCaseID, Note
12 CASE FILING EVENT YourCaseID, CaseNo, DateFiled, CourtNumber, CalendarNumber, Judge, CaseManagementDate, CaseManagementTime
Defendants[]: YourJobID, YourDefendantID, Defendant, HearingDate, HearingTime, Department
Sent when a case has been filed with the court. Each defendant entry corresponds to a job. CaseManagementDate format: YYYY-MM-DD. CaseManagementTime format: HH:MM (24-hour clock, e.g., 13:00 = 1pm).
View Sample JSON
{
    "YourCaseID": "CASE-2024-001",
    "CaseNo": "2024-CV-12345",
    "DateFiled": "2024-12-15",
    "CourtNumber": "11",
    "CalendarNumber": "5",
    "Judge": "Wapner",
    "CaseManagementDate": "2025-02-20",
    "CaseManagementTime": "14:00",
    "Defendants": [
        {
            "YourJobID": "JOB-001",
            "YourDefendantID": "DEF-001",
            "Defendant": "John Doe",
            "HearingDate": "2025-01-15",
            "HearingTime": "09:00",
            "Department": "Room 101"
        },
        {
            "YourJobID": "JOB-002",
            "YourDefendantID": "DEF-002",
            "Defendant": "Jane Doe",
            "HearingDate": "2025-01-15",
            "HearingTime": "09:30",
            "Department": ""
        }
    ]
}
13 DEFID REQUEST YourCaseID, OurJobID, Recipient, Address1, Address2, City, State, Zip
14 DEFID RESPONSE You send in: RASCaseID, ServerJobID, NewRecipientID, Recipient
$data = [
    "Function" => "DEFID RESPONSE",
    "Receiver" => "DEF",
    "Case" => [
        "RASCaseID" => "12345",
        "ServerJobID" => "12345444",
        "NewRecipientID" => "DEF 008",
        "Recipient" => "JANE DOE"
    ]
]
15 INCOMING CASE LEVEL DOCUMENT You send in your caseID that you sent when you sent the jobs and attachment array. Send it with the INCOMING_CASE_LEVEL_DOCUMENT function. Receiver is MANDATORY (the JEN code you sent the case to). Response: OK, TransID: ...
$data = [
    "Function" => "INCOMING_CASE_LEVEL_DOCUMENT",
    "Receiver" => "TESTA",
    "CaseIdentifier" => "20-02977XXR_602559",
    "Attachments" => [
        "DocRefNumber" => "20-02977XXR",
        "DocSubRefNumber" => "A48BC3DDX-8883-4992-B4D8-7B4F1GGG5E4E",
        "DocumentDate" => "2025-10-01",
        "DocumentType" => "ComplaintPackadgeExecuted",
        "FileExtension" => "pdf",
        "FileBase64Data" => "JVBERi0xLjQKJcfs..."
    ]
]
16 LAST DEFENDANT COMPLETED YourCaseID, YourRecipientID, YourJobID, CaseNo, ClientFileNum, OurCaseID, DateLastDefCompleted, LastDefendantName
Case-level event sent once per case when the process server marks the last defendant on the case as completed. YourRecipientID / YourJobID / LastDefendantName identify that final defendant. DateLastDefCompleted format: YYYY-MM-DD. Fired at most once per case by the sender.
View Sample JSON
{
    "YourCaseID": "26-27483IL_1466160",
    "YourRecipientID": "270289",
    "YourJobID": "26-27483IL",
    "CaseNo": "2026FC27",
    "ClientFileNum": "26-27483IL",
    "OurCaseID": 1363,
    "DateLastDefCompleted": "2026-09-23",
    "LastDefendantName": "Secretary of Housing and Urban Development"
}
17 CASE WITHDRAWN YourCaseID, WholeCase, YourJobIDs
The sender has withdrawn a case, or some of its jobs, that you already picked up. Stop work on every job in YourJobIDs (matched by the sender's JEN code + YourJobID, as sent in the original NEWCASE). WholeCase true means the whole case is withdrawn, including its case-level documents. Sent by CANCELCASE; never sent twice for the same job.
View Sample JSON
{
    "Function": "CASE WITHDRAWN",
    "YourCaseID": "CASE-2024-001",
    "WholeCase": false,
    "YourJobIDs": ["JOB-002"]
}


SENDING EVENTS (POSTBACKS)

Use POSTBACKS to send events about jobs you were sent: Job Completed (2), Document Scanned (3), Attempt (4), Invoice (6), Other Note (7), Case Level Note (11), Case Filing Event (12) and Last Defendant Completed (16). You can send one event or many in a single call, and they can be different event types.

Each item in PostBacks has these fields:

  • id (string): YOUR identifier for this event. It is returned to you in the response so you can tell which events were accepted.
  • etype (integer): The Event Code. See EVENT CODES above.
  • sender (string): YOUR JEN code.
  • receiver (string): The JEN code of the party you are sending the event to (normally the party that sent you the job).
  • jstext (string): The event fields for that Event Code (see EVENT CODES above), encoded as a JSON string, not as a nested object.

YourCaseID, YourJobID and YourRecipientID inside jstext are the IDs the receiver sent you in NEWCASE, so they can match the event to their job.

$data = [
    "Function" => "POSTBACKS",
    "PostBacks" => [
        [
            "id" => "1001",
            "etype" => 4,
            "sender" => "YOURCODE",
            "receiver" => "TESTA",
            "jstext" => json_encode([
                "YourCaseID" => "CASE-2024-001",
                "YourJobID" => "JOB-5678",
                "Dt" => "2024-12-03",
                "Tm" => "14:30",
                "Address1" => "123 Main Street",
                "Address2" => "Apt 4B",
                "City" => "Miami",
                "State" => "FL",
                "Zip" => "33101",
                "Note" => "No answer at door. Left door hanger."
            ])
        ],
        [
            "id" => "1002",
            "etype" => 7,
            "sender" => "YOURCODE",
            "receiver" => "TESTA",
            "jstext" => json_encode([
                "YourCaseID" => "CASE-2024-001",
                "YourJobID" => "JOB-5678",
                "YourRecipientID" => "R001",
                "Recipient" => "John Doe",
                "Dt" => "2024-12-03",
                "Tm" => "15:10",
                "Note" => "Job Accepted and Imported"
            ])
        ],
        [
            "id" => "1003",
            "etype" => 3,
            "sender" => "YOURCODE",
            "receiver" => "TESTA",
            "jstext" => json_encode([
                "YourCaseID" => "CASE-2024-001",
                "YourJobID" => "JOB-5678",
                "YourRecipientID" => "R001",
                "CaseNo" => "2024-CV-12345",
                "DocType" => "Affidavit of Service",
                "ScanID" => "58099",
                "Filename" => "affidavit_JOB-5678.pdf",
                "DownloadLink" => "https://example.com/viewdocument.php?id=58099&token=abc123"
            ])
        ]
    ]
];
                            
Encoded as a JSON string, that is:
{"Function":"POSTBACKS","PostBacks":[
{"id":"1001","etype":4,"sender":"YOURCODE","receiver":"TESTA","jstext":"{\"YourCaseID\":\"CASE-2024-001\",\"YourJobID\":\"JOB-5678\",\"Dt\":\"2024-12-03\",\"Tm\":\"14:30\",\"Address1\":\"123 Main Street\",\"Address2\":\"Apt 4B\",\"City\":\"Miami\",\"State\":\"FL\",\"Zip\":\"33101\",\"Note\":\"No answer at door. Left door hanger.\"}"},
{"id":"1002","etype":7,"sender":"YOURCODE","receiver":"TESTA","jstext":"{\"YourCaseID\":\"CASE-2024-001\",\"YourJobID\":\"JOB-5678\",\"YourRecipientID\":\"R001\",\"Recipient\":\"John Doe\",\"Dt\":\"2024-12-03\",\"Tm\":\"15:10\",\"Note\":\"Job Accepted and Imported\"}"},
{"id":"1003","etype":3,"sender":"YOURCODE","receiver":"TESTA","jstext":"{\"YourCaseID\":\"CASE-2024-001\",\"YourJobID\":\"JOB-5678\",\"YourRecipientID\":\"R001\",\"CaseNo\":\"2024-CV-12345\",\"DocType\":\"Affidavit of Service\",\"ScanID\":\"58099\",\"Filename\":\"affidavit_JOB-5678.pdf\",\"DownloadLink\":\"https://example.com/viewdocument.php?id=58099&token=abc123\"}"}
]}
The response is one result per event:
[{"id":"1001","result":"OK","transid":"20250507074040681b0e781476f198560565"},
 {"id":"1002","result":"OK","transid":"20250507074040681b0e781476f198560571"},
 {"id":"1003","result":"OK","transid":"20250507074040681b0e781476f198560588"}]
Only treat an event as delivered when its result is OK. Anything else (e.g. ERROR, Failed to insert) should be retried.

Photos for Job Completed (2) and Attempt (4) go inside that event's jstext as a Photos array (see the Sample JSON for those Event Codes above). There is no separate photo function.



GET EVENTS

                            $data = [
    "Function" => "GETEVENTS"
    ];
                        
Encode this into a JSON string and send it to the server: {"Function":"GETEVENTS"}

  • You get up to 100 waiting events per call, oldest first. If there are none you get: No events found
  • An event keeps coming back on every GETEVENTS until you mark it done with REMOVETRANS. Save it on your side first, then remove it.
  • Once GETEVENTS has handed you a case, the sender can no longer quietly pull it back. If they withdraw it, or some of its jobs, you will get Event Code 17 CASE WITHDRAWN telling you which jobs to stop. Your system must handle Event Code 17. See CANCELCASE.
An Example Of A Response (If Successful) Would Be:

Explanation Of Data Received Back

1. id (integer)

Description: This is the internal ID of the Event.

Example: 5357546

2. sender (string)

Description: The identifier or code for the sending party.

Example: "TEST"

3. receiver (string)

Description: The identifier or code for the receiving party.

Example: "YOU"

4. etype (integer)

Description: The Event Code for this Event. See Above For List Of Event Codes.

Example: 7

5. xserial (string)

Description: This is a TransactionID. You will need this then you call REMOVETRANS later to tell JEN that you have fetched this event and not to show it again.

Example: 20250507075622681b1226ec43d346726488

6. jsonfile (string)

Description: This is JSON of the Event (It has extra slashes because it is JSON inside of JSON).

Example: {\"id\":\"5\",\"etype\":\"7\",\"sender\":\"TEST\",\"receiver\":\"YOU\",\"jstext\":\"{\\\"YourCaseID\\\":\\\"67890\\\",\\\"YourJobID\\\":\\\"B002\\\",\\\"YourRecipientID\\\":\\\"R002\\\",\\\"Recipient\\\":\\\"Another Recipient\\\",\\\"Note\\\":\\\"Job Accepted and Imported\\\"}\"}

Fields:
  • YourCaseID (string): Unique identifier for the case.
    Example: "67890"
    This field is YOUR CASE-LEVEL ID NUMBER. If This is a case-level event then it will not include further job identifiers.
  • YourJobID (string): If this is a job-level event then it will contain job-identifier information. This is the YourJobID that you sent in originally with NEWCASE to identify this particular job inside of this case.
    Example: B002
  • YourRecipientID (string): This is the ID that you sent in for this Recipient.
    Example: R002


  • Additional Fields Will Be Present Depending On The Type Of Event. See EVENT CODES Section Above.

    REMOVE EVENTS

    $data = [
        "Function" => "REMOVETRANS",
        "TransIDs" => [
        "20250507075622681b1226ec43d346726777",
        "20250507075622681b1226ec43d346726488"
      ]
    ];
                            
    Encode this into a JSON string and send it to the server: {"Function": "REMOVETRANS","TransIDs": ["20250507075622681b1226ec43d346726777","20250507075622681b1226ec43d346726488"]}

    Response:
    OK, TransID: 20250507075622681b1226ec43d346726777 marked as done
    OK, TransID: 20250507075622681b1226ec43d346726488 marked as done
    


    LOOK UP A JEN USER

    $data = [
        "Function" => "GETJENUSER",
        "JENCode" => "TESTA"
    ];
                            
    Encode this into a JSON string and send it to the server: {"Function":"GETJENUSER","JENCode":"TESTA"}

    Response:
    [{"ID":9,"JENCode":"TESTA","IsLawFirm":0,"AgencyName":"Your Agency Name, Inc.","Address1":"...","Address2":"","City":"Conroe","State":"TX","Zip":"...","Phone":"...","Email":"..."}]
    If the code does not exist you will get: No user found: CODE
    GETJENUSER finds every member by code, including members hidden from the member directory below. Partner logins may call it too.

    LIST ALL JEN MEMBERS (MEMBER DIRECTORY)

    $data = [
        "Function" => "LISTJENUSERS"
    ];
                            
    Encode this into a JSON string and send it to the server: {"Function":"LISTJENUSERS"}

    Any JEN login can call it: members, partner logins and JEN support. It takes no other fields. It returns every active JEN member that has not been hidden from the directory, sorted by company name, with the same fields as GETJENUSER. Disabled members, partner logins and JEN support's own login are never listed. Every member is listed by default; a member is hidden only when its partner (with SETJENUSERLISTED or the partner Members page) or JEN support turns it off. A hidden member can still be looked up by code with GETJENUSER.

    Response (a JSON list; [] if nobody is listed):
    [{"ID":9,"JENCode":"SMITHJONES","IsLawFirm":0,"AgencyName":"Smith & Jones Process Serving LLC","Address1":"1 Main St","Address2":"","City":"Moline","State":"IL","Zip":"61265","Phone":"309-555-1212","Email":"office@smithjones.example"},
     {"ID":12,"JENCode":"TESTA","IsLawFirm":0,"AgencyName":"Your Agency Name, Inc.","Address1":"...","Address2":"","City":"Conroe","State":"TX","Zip":"...","Phone":"...","Email":"..."}]
    Without a login (or with a wrong one) you get the usual HTTP 403 / 401 login errors, see PING.

    WITHDRAW A CASE OR JOBS YOU SENT

    $data = [
        "Function" => "CANCELCASE",
        "Receiver" => "TESTA",
        "YourCaseID" => "CASE-2024-001",
        "YourJobIDs" => ["JOB-002"]
    ];
                            
    Encode this into a JSON string and send it to the server: {"Function":"CANCELCASE","Receiver":"TESTA","YourCaseID":"CASE-2024-001","YourJobIDs":["JOB-002"]}

    Receiver (the JEN code you sent the case to) and YourCaseID are mandatory. Leave out YourJobIDs to withdraw the whole case. You can only withdraw cases you sent.
    • If the receiver has not picked the case up yet, JEN removes it (or just those jobs) and they never see it. Withdrawing the whole case also removes its case-level documents that are still waiting.
    • If the receiver already picked it up, JEN sends them Event Code 17 CASE WITHDRAWN so they stop work.
    Response:
    {"Result":"OK","YourCaseID":"CASE-2024-001","Jobs":[{"YourJobID":"JOB-002","Result":"WITHDRAW NOTICE SENT"}],"DocumentsDropped":0,"TransID":"20250507075622681b1226ec43d346726777"}
    Each job's Result is one of: DROPPED (receiver never got it), WITHDRAW NOTICE SENT (Event Code 17 sent), ALREADY WITHDRAWN (nothing new to do), NOT FOUND (no such job in that case). TransID is the Event Code 17 transaction, or null if none was needed. Calling it again is safe.
    If the case does not exist you will get: Case not found: CASE-2024-001

    PARTNER LOGINS (SOFTWARE COMPANIES)

    A partner is a software company that puts its customers (agencies) on JEN, for example RocketServe. A partner login is a manager, not a member: it creates and manages only its own members, and sees only those members and their events. It cannot see or touch anyone else's members or events.
    • Who gets one: JEN support creates partner logins on request. You use it exactly like a member login: Basic Auth in the header, JSON in the body, same address.
    • Your members: members you create with CREATEJENUSER, plus any existing JEN member JEN support assigns to your software company. A member that is not yours is reported exactly like a member that does not exist: Member not found: CODE.
    • Allowed functions: a partner login may call only PING, GETJENUSER, LISTJENUSERS, CREATEJENUSER, RESETJENUSER, DISABLEJENUSER, ENABLEJENUSER and SETJENUSERLISTED. Every other function (NEWCASE, POSTBACKS, GETEVENTS, REMOVETRANS, ...) answers Unauthorized. A partner does not send or receive cases itself; its members do, with their own logins.
    • JEN support: JEN support's own login may call these four functions on any member.
    • Member logins cannot use these four calls: CREATEJENUSER, RESETJENUSER, DISABLEJENUSER and ENABLEJENUSER answer Unauthorized to an ordinary member login.
    • Web section: a partner login also works on the JEN website. It lands on /partner/, with a Jobs tab (search your members' jobs, view the JSON, requeue Posted or Quarantined jobs) and a Members tab (list, add, reset password, disable / re-enable, edit address and contact).
    • Assigning existing members: JEN support assigns a member to a software company in the admin Users page. A member's whole history moves with it, including events from before it was assigned.
    Errors on every call here (plain text, same as the other functions): Unauthorized (your login type may not make this call), Member not found: CODE, Missing required fields: ..., Invalid value for FIELD, Email already belongs to a JEN member, Company name has no usable letters or digits, JEN is busy, please try again and Member was disabled by JEN support and can only be re-enabled by JEN support. Each is explained with the call it belongs to. Error responses are plain text with HTTP status 200, and they begin with a newline, for example \nMember not found: SMITHJONES, so trim the response before comparing it. Login failures (HTTP 403) are listed under PING above.

    CREATE A JEN MEMBER

    $data = [
        "Function" => "CREATEJENUSER",
        "CompanyName" => "Smith & Jones Process Serving LLC",
        "Address1" => "100 Main St",
        "Address2" => "Suite 4",
        "City" => "Conroe",
        "State" => "TX",
        "Zip" => "77301",
        "Phone" => "936.555.1212",
        "Email" => "office@smithjones.example",
        "FirstName" => "Pat",
        "LastName" => "Smith",
        "IsLawFirm" => 0
    ];
                            
    Encode this into a JSON string and send it to the server. Partner logins (and JEN support) only.
    FieldRequired?Notes
    CompanyNameYesThe member's name. The JEN code is made from it (rule below).
    Address1Yes
    Address2No
    CityYes
    StateYes
    ZipYes
    PhoneYes
    EmailYesMust be a valid email address. Also how a repeat call finds the member (see below).
    FirstName, LastNameNoContact name.
    IsLawFirmNo1 for a law firm, otherwise 0 (default). Any non-empty value other than "0" counts as 1.
    Values are trimmed. Unknown extra fields are ignored, and every text field is limited to 255 characters (longer is refused with FIELD is too long (255 characters max)). A field sent as a list or object is refused with Invalid value for FIELD (for example Invalid value for City). Missing, blank or malformed required fields are all named in one message, for example Missing required fields: City, Email.

    Response when a new member is created:
    {"Result":"OK","Created":true,"Active":true,"JENCode":"SMITHJONES","Username":"smithjones4821","Password":"aB3dE5fG7h"}
    Username and Password are the member's login for every member function above. Save them: the password is also shown again if you repeat the call or call RESETJENUSER for a new one. The member belongs to your software company and starts active.

    The JEN code rule (the code is chosen by JEN, you cannot pick it):
    1. Take the company name and strip punctuation and symbols (accented letters become plain letters).
    2. Drop business-type words: LLC, Inc, Ltd, Co, Corp, Corporation, PLLC, LLP, LP, PC, PA, Company and generic industry words: Process, Processing, Serving, Serves, Server, Servers, Service, Services, Legal, Support, Investigations, Investigative, Agency, and, the.
    3. Squish what is left together, uppercase, letters A-Z and digits 0-9 only, at most 20 characters.
    4. If nothing is left after step 2, the full squished name is used instead. If there is still nothing (a name made only of symbols), you get Company name has no usable letters or digits.
    5. If the code is already taken, JEN adds 2, 3, ... (shortening the name so the code stays within 20 characters). A code counts as taken if any JEN member has it, or if it was ever used as a sender or receiver of an event, so a code from a deleted member is never given to a new one.
    Examples:
    Company NameJEN Code
    Smith & Jones Process Serving LLCSMITHJONES
    Fortis Legal SupportFORTIS
    Alabama Legal Solutions LLCALABAMASOLUTIONS
    TJC Process Service Ltd.TJC
    Medley Serves & Investigations, LLCMEDLEY
    Process Serving LLC (nothing left after step 2)PROCESSSERVINGLLC
    Fortis Legal Support again (code taken)FORTIS2
    Username is the JEN code in lowercase (first 12 characters) plus 4 random digits. Password is 10 random letters and digits.

    Calling again with the same email is safe. The email is compared ignoring case and surrounding spaces, against all JEN logins (members, partner logins and JEN support), including disabled ones:
    • The email belongs to one of your members: nothing is changed and that member is returned with "Created":false and its current Username and Password. This also holds when two calls arrive at the same moment: only one member is made.
      {"Result":"OK","Created":false,"Active":true,"JENCode":"SMITHJONES","Username":"smithjones4821","Password":"aB3dE5fG7h"}
      If that member is disabled it is still returned, with "Active":false, and it is not re-enabled. Use ENABLEJENUSER for that.
    • The email belongs to anyone else: Email already belongs to a JEN member. The message does not say whose.
    Other errors: Missing required fields: ..., Invalid value for FIELD, Company name has no usable letters or digits, JEN is busy, please try again (another member creation or edit was in progress and did not finish within 10 seconds; send it again), and Unauthorized for a member login.

    RESET A MEMBER'S PASSWORD

    $data = [
        "Function" => "RESETJENUSER",
        "JENCode" => "SMITHJONES"
    ];
                            
    Encode this into a JSON string and send it to the server: {"Function":"RESETJENUSER","JENCode":"SMITHJONES"}

    Issues a new 10 character password, saves it and returns it. The old password stops working at once, and the member's website sessions are ended, so a leaked password stops working everywhere.
    {"Result":"OK","JENCode":"SMITHJONES","Username":"smithjones4821","Password":"xY9zA2bC4d"}
    A partner can reset only its own members. If the code is not one of your members (or does not exist, or is not a member login) you get Member not found: SMITHJONES. A member login gets Unauthorized. A blank or missing JENCode gives Member not found: and a list or object gives Invalid value for JENCode.

    DISABLE OR RE-ENABLE A MEMBER

    $data = [
        "Function" => "DISABLEJENUSER",   // or "ENABLEJENUSER"
        "JENCode" => "SMITHJONES"
    ];
                            
    Encode this into a JSON string and send it to the server: {"Function":"DISABLEJENUSER","JENCode":"SMITHJONES"}

    DISABLEJENUSER turns the member's login off everywhere (API and website) and ends their website sessions. ENABLEJENUSER turns it back on. Repeating either call is harmless. Events already waiting for a disabled member stay queued; they just cannot be picked up until the member is enabled again. A disabled member trying to log in gets Forbidden - Account disabled.
    {"Result":"OK","JENCode":"SMITHJONES","Active":false}
    Active is false after DISABLEJENUSER and true after ENABLEJENUSER.

    JEN support's disable wins. If JEN support disables a member, only JEN support can enable it again. Your ENABLEJENUSER call is refused with:
    Member was disabled by JEN support and can only be re-enabled by JEN support
    If you disabled the member yourself, you can enable it again. Your own disable never overrides JEN support's.

    Other errors: Member not found: CODE (not one of your members), Invalid value for JENCode, and Unauthorized for a member login.

    SHOW OR HIDE A MEMBER IN THE MEMBER DIRECTORY

    $data = [
        "Function" => "SETJENUSERLISTED",
        "JENCode" => "SMITHJONES",
        "Listed" => false     // false = hide from LISTJENUSERS, true = show again
    ];
                            
    Encode this into a JSON string and send it to the server: {"Function":"SETJENUSERLISTED","JENCode":"SMITHJONES","Listed":false}

    Partner logins (for their own members) and JEN support (for any member) only. Every member starts out listed. Hiding a member only removes it from LISTJENUSERS: it can still log in, send and receive cases, and be found by code with GETJENUSER. Repeating the call is harmless.

    Listed is required: true/false, 1/0, or the strings "true"/"false", "yes"/"no", "on"/"off".
    {"Result":"OK","JENCode":"SMITHJONES","Listed":false}
    Errors: Missing required fields: Listed, Invalid value for Listed, Member not found: CODE (not one of your members), Invalid value for JENCode, and Unauthorized for a member login.

    SENDING IN NEW JOBS

                                $data = [
        "Function" => "NEWCASE",
        "Receiver" => "DEF",
        "Case" => [
            "YourCaseID" => "12345",
            "LawFirmName" => "Test Law Firm, P.A.",
            "LawFirmAddress" => "123 Test Law Firm Lane",
            "LawFirmAddress2" => "Suite 234",
            "LawFirmCity" => "Miami",
            "LawFirmState" => "FL",
            "LawFirmZip" => "33030",
            "LawFirmPhone" => "305.555.1212",
            "LawFirmEmail" => "test@ttttr.com",
            "AttorneyName" => "John Holmes",
            "AttorneyBarNum" => "999999",
            "CaseLevelLawFirmFileNum" => "TEST-001CASE",
            "CourtName" => "Supreme Court",
            "CourtAddress" => "123 Main St",
            "CourtAddress2" => "Suite 200",
            "CourtCity" => "Anytown",
            "CourtState" => "CA",
            "CourtZip" => "90210",
            "CourtCounty" => "Los Angeles",
            "PlaintiffCaption" => "Test Plaintiff, Test Plaintiffs Bank and XYZ Lending Corporation As Successor Of XZZ Corporation",
            "PlaintiffRole" => "Claimant(s)",
            "DefendantCaption" => "Test Defendant, Test Defenants Unknown Spouse, John Doe and Jane Doe",
            "DefendantRole" => "Respondent(s)",
            "CourtCaseNo" => "987654321",
            "DateFiled" => "2023-09-19",
            "RequestorName" => "Law Firm",
            "RequestorEmail" => "lawfirm@example.com",
            "Jobs" => [
                [
                    "Job" => [
                        "YourJobID" => "A001",
                        "YourRecipientID" => "R001",
                        "Recipient" => "Recipient Name",
                        "RecipientRole" => "Defendant",
                        "Action" => "Serve And File",
                        "Priority" => "Routine",
                        "DueDate" => "2023-10-10",
                        "HearingDate" => "2024-02-03",
                        "HearingTime" => "14:15",
                        "JaxNum" => "123456",
                        "JobLevelLawFirmFileNum" => "TEST-001-A001",
                        "DocumentString" => "Summons; Complaint; Exhibits",
                        "Instructions" => "Specific job instructions",
                        "JobType" => "Service of Process - Routine",
                        "Documents" => [
                            [
                                "DocumentID" => "D001",
                                "DocumentType" => "Service Documents",
                                "DocumentFileName" => "Document1.pdf",
                                "DocumentURL" => "https://rocketserve.app/viewscandoc.php?job=11617473&owner=27&token={AADF1EE0-5F44-8158-20B7-E562D414F371}&scanid=8966245",
                                "UseBase64" => "1",
                                "Base64Data" => "JVBERi0xLjQKJcfs..."
                            ],
                            [
                                "DocumentID" => "D002",
                                "DocumentType" => "Service Documents",
                                "DocumentFileName" => "Document2.pdf",
                                "DocumentURL" => "https://rocketserve.app/viewscandoc.php?job=11617473&owner=27&token={AADF1EE0-5F44-8158-20B7-E562D414F371}&scanid=8966192",
                                "UseBase64" => "1",
                                "Base64Data" => "JVBERi0xLjQKJcfs..."
                            ]
                        ],
                        "Addresses" => [
                            [
                                "Address" => [
                                    "YourAddrID" => "Addr001",
                                    "Address" => "456 Elm St",
                                    "Address2" => "Apt 3B",
                                    "City" => "Othertown",
                                    "State" => "NY",
                                    "Zip" => "10001"
                                ]
                            ],
                            [
                                "Address" => [
                                    "YourAddrID" => "Addr002",
                                    "Address" => "789 Pine St",
                                    "Address2" => "",
                                    "City" => "Sometown",
                                    "State" => "FL",
                                    "Zip" => "33101"
                                ]
                            ]
                        ]
                    ]
                ]
            ]
        ]
                            


    So, you send in that JSON string.

    The response (if successful) would be:

    OK, TransID: 2024092915225166f970cb1351f144055868

    Explanation Of Fields:

    1. Function (string)

    Description: Specifies the function or action being requested.

    Example: "NEWCASE"

    Constraints: Must be a valid function keyword

    2. Receiver (string)

    Description: The identifier or code for the receiving party.

    Example: "DEF"

    Constraints: Must be a predefined code for the receiving party.

    3. Case (object)

    Description: Contains details of the legal case.

    Fields:

    • YourCaseID (string): Unique identifier for the case.
      Example: "12345"
      This field is MANDATORY. Even if you are only sending in one job and have already sent the case earlier, we use this field to stack the job inside the existing case with YOUR CASE-LEVEL ID NUMBER. This must be unique for each COURT CASE.
    • CourtName (string): FULL Name of the court handling the case AS IT SHOULD APPEAR ON THE PROOF OF SERVICE.
      Example: "SUPREME COURT OF THE STATE OF NEW YORK - COUNTY OF QUEENS"
    • LawFirmName (string): This is the name of the law firm.
      Example: "Test Law Firm, P.A."
      This field is MANDATORY. If you don't want the reciever to have this, just put BLANK (in capital letters).
    • LawFirmAddress (string): Street address of the law firm.
      Example: "123 Test Law Firm Lane"
    • LawFirmAddress2 (string): Secondary address information such as the suite number.
      Example: "Suite 234"
    • LawFirmCity (string): City of the law firm.
      Example: "Miami"
    • LawFirmState (string): State of the law fimr
      Example: "FL"
    • LawFirmZip (string): Zip Code of the law firm.
      Example: "33030"
    • LawFirmPhone (string): Phone number of the law firm. Some CA affiavits need this.
      Example: "305.555.1212"
    • LawFirmEmail (string): Email Addresss of the law firm (some CA forms need this).
      Example: "test@ttttr.com"
    • AttorneyName (string): Name of the attorney
      Example: "John Holmes"
    • AttorneyBarNum (string): Bar number of the attorney.
      Example: "999999"
    • CaseLevelLawFirmFileNum (string): This is a file number that the law firm has at the case level for the case.
      Example: "TEST-001CASE"
      While not mandatory, it is strongly suggested to send this.
    • CourtName (string): FULL Name of the court handling the case AS IT SHOULD APPEAR ON THE PROOF OF SERVICE.
      Example: "SUPREME COURT OF THE STATE OF NEW YORK - COUNTY OF QUEENS"
    • CourtAddress (string): Street address of the court.
      Example: "123 Main St"
    • CourtAddress2 (string, optional): Secondary address information such as suite number.
      Example: "Suite 200"
    • CourtCity (string): City where the court is located.
      Example: "Anytown"
    • CourtState (string): State where the court is located, represented by a two-letter code.
      Example: "CA"
    • CourtZip (string): ZIP code of the court's location.
      Example: "90210"
    • PlaintiffCaption (string): Full Name Of The Plaintiff(s) As They Appear In The CASE STYLE
      Example: "Test Plaintiff, Test Plaintiffs Bank and XYZ Lending Corporation As Successor Of XZZ Corporation"
    • PlaintiffRole (string): Legal role of the plaintiff(s).
      Example: "Claimant(s)"
    • DefendantCaption (string): Full Name Of The Defendant(s) As They Appear In The CASE STYLE
      Example: "Test Defendant, Test Defenants Unknown Spouse, John Doe and Jane Doe"
    • DefendantRole (string): Legal role of the defendant(s).
      Example: "Respondent(s)"
    • CourtCaseNo (string): Official case number assigned by the court.
      Example: "987654321"
    • DateFiled (string): Date the case was filed in the court, formatted as YYYY-MM-DD.
      Example: "2023-09-19"
    • RequestorName (string): Name of the entity or person requesting this case action.
      Example: "Jack Johnson"
    • RequestorEmail (string): Email address of the requestor.
      Example: "jack@gmail.com"
      The Requestor Fields Are Important. These Are Who Gets Email Notifications

    4. Jobs (array of objects)

    Description: A list of jobs associated with this case.

    Fields:

    • Job (object): Contains details about a specific job.
      • YourJobID (string): Unique identifier for the job.
        Example: "12345"
        This Field Is Mandatory. We Use This As Your Reference Number.
      • YourRecipientID (string): Unique identifier for the recipient.
        Example: "1854564"
        This Field Is Not Mandatory, But We Use This To Match Up New Addresses You May Send Over Later To Go Under This Recipient.
      • Recipient (string): Name of the recipient.
        Example: "Recipient Name"
      • RecipientRole (string): The Role of the Recipient. Defaults to Defendant if empty
        Example: "Defendant"
      • DueDate (string): Due date for the job, formatted as YYYY-MM-DD.
        Example: "2023-10-10"
      • HearingDate (string): Hearing date for the job, formatted as YYYY-MM-DD.
        Example: "2024-02-03"
      • HearingTime (string): Hearing time for the job, formatted as HH:MM (24 hr).
        Example: "14:12"
      • JaxNum (string): A reference number for the job.
        Example: "123456"
      • JobLevelLawFirmFileNum (string): The law firm's file / reference number for this job (this recipient). Optional. Use it when the law firm tracks each recipient under its own number; the case-wide number goes in CaseLevelLawFirmFileNum.
        Example: "TEST-001-A001"
      • Instructions (string): Specific instructions for this job.
        Example: "Specific job instructions"
      • JobType (string): Type of job.
        Example: "Service of Process - Routine"
        Send your own wording; your process server matches each value you use to one of theirs once, and jobs with a value they have not matched yet are held until they do.
      • Action (string): What you want done with the documents for this job. Optional.
        Example: "Serve And File"
        Send your own wording; your process server matches each value you use to one of theirs once, and jobs with a value they have not matched yet are held until they do.
      • Priority (string): How urgent the job is. Optional.
        Example: "Routine"
        Send your own wording; your process server matches each value you use to one of theirs once, and jobs with a value they have not matched yet are held until they do.
      • DocumentString (string): The list of documents to be served AS YOU WANT THEM ON YOUR PROOF OF SERVICE.
        Example: "Summons, Complaint, Exhibits"
      • Documents (array of objects): List of documents associated with this job.
        • Document (object): Contains details about a specific document.
        • DocumentID (string): Unique identifier for the document.
          Example: "D001"
        • DocumentType (string): Type of document.
          This may only be: "Service Documents"
        • DocumentDesc (string): Description of the document.
          Example: "Summons and Complaint"
        • DocumentFileName (string): File name of the document.
          Example: "Document1.pdf"
        • DocumentURL (string): URL where the document can be viewed.
          Example: "https://rocketserve.app/viewscandoc.php?job=..."
        • UseBase64 (string): Indicates if the document is sent as Base64 encoded data so there is no need to use DocumentURL to download it.
          Example: "1"
        • Base64Data (string): Base64 encoded data of the document.
          Example: "JVBERi0xLjQKJcfs..."
      • Addresses (array of objects): List of addresses associated with this job.
        • Address (object): Contains details about a specific address.
        • YourAddrID (string): Unique identifier for the address.
          Example: "Addr001"
        • Address (string): Street address.
          Example: "456 Elm St"
        • Address2 (string, optional): Secondary address information.
          Example: "Apt 3B"
        • City (string): City.
          Example: "Othertown"
        • State (string): State.
          Example: "NY"
        • Zip (string): Zip Code.
          Example: "10001"
        • County (string): County.
          Example: "Any County"