I answered Code First, because we generate our specs from the code, but we usually discuss a lot about the design (routes, names, arguments, return values) before to start coding.
This was one of the very reason we choose to use FlaskRestplus (plus ReDoc to customize the rendering and add OpenAPI vendor extensions, like code samples). One of the key point is that it guarantees that the specs we give to our clients is accurate and actually matches the real behavior of the API. We also extended Flask Restplus to provide both public and internal docs. This lets us have «undocumented» endpoints but have the same doc for ourselves (but the scope required to call these is hardly even given to a client, so we hide these endpoints from them)
When we start big features, we even regularly write the code first, which only return 501 Not implemented error, but it let us see the routes, arguments and specs generated live, in the real context, which makes it even much easier to reason about and discuss, see how consistent it is with the rest of the existing endpoints, ...
Another important point for me is that the endpoint documentation is extracted from the implementation comment blocks (and decorators). That means that when we change/extend the implementation -which implies the documentation should also be updated - those 2 pieces are very close to each other in the code base. This brings 2 benefits: it’s much more obvious for the developer to think of the doc update, because of the proximity. And it’s easier for the reviewers to spot missing docs updates, for the same reason.