Mocks are instantiations of real object in your system, complete with all the necessary plumbing and expected functionality of that real object. I will use a mock API endpoint (an instantiation of a real API endpoint that doesn't actually affect other systems/data) that responds appropriately to a given input (i.e. returns an error, returns the expected object).
Stubs are incomplete. I use stubs to fake something that I don't know exactly what it needs to be, yet. I frequently will create stub API end points that are only designed to return a canned response, while I figure out what I actually need from the API I have yet to build.
To put it another way:
A mock is a fake based on something that actually exists in your system or application.
A stub is a fake based on something that either does not exist in the necessary state, that you do not need actual business logic of, or a place holder until other code is completed.